cgen 0.16.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/.gitignore +5 -0
- data/History.txt +199 -0
- data/README.txt +34 -0
- data/examples/bench.rb +14 -0
- data/examples/complex.rb +63 -0
- data/examples/complex2.rb +48 -0
- data/examples/cshadow-example.rb +55 -0
- data/examples/cshadow-point.rb +58 -0
- data/examples/ctest.rb +34 -0
- data/examples/ctest2.rb +32 -0
- data/examples/ctest3.rb +179 -0
- data/examples/ctest4.rb +18 -0
- data/examples/ctest5.rb +27 -0
- data/examples/example-ruby-talk-30April2004.rb +65 -0
- data/examples/fixed-array.rb +221 -0
- data/examples/inherit-example.rb +26 -0
- data/examples/inherit-example.txt +80 -0
- data/examples/instance-eval.rb +66 -0
- data/examples/ivset.rb +55 -0
- data/examples/marshal-test.rb +19 -0
- data/examples/matrix.rb +91 -0
- data/examples/modular-def.rb +87 -0
- data/examples/objattr.rb +46 -0
- data/examples/opaque-struct-test.rb +36 -0
- data/examples/sample.rb +184 -0
- data/examples/struct.rb +103 -0
- data/examples/test.rb +24 -0
- data/examples/yaml.rb +56 -0
- data/install.rb +1015 -0
- data/lib/cgen/attribute.rb +414 -0
- data/lib/cgen/cgen.rb +2041 -0
- data/lib/cgen/cshadow.rb +1037 -0
- data/lib/cgen/inherit.rb +46 -0
- data/rakefile +42 -0
- data/tasks/ann.rake +80 -0
- data/tasks/bones.rake +20 -0
- data/tasks/gem.rake +201 -0
- data/tasks/git.rake +40 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +51 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +292 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- data/tasks/zentest.rake +36 -0
- data/test/test-attribute.rb +430 -0
- data/test/test-cgen.rb +127 -0
- data/test/test-cshadow.rb +289 -0
- data/test/test.rb +17 -0
- metadata +123 -0
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            require 'cgen/cshadow'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class Parent
         | 
| 4 | 
            +
              include CShadow
         | 
| 5 | 
            +
              
         | 
| 6 | 
            +
              shadow_attr_accessor :ruby_str => String
         | 
| 7 | 
            +
              shadow_attr_accessor :c_int => "int c_int"
         | 
| 8 | 
            +
            end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            class Child < Parent
         | 
| 11 | 
            +
              shadow_attr_accessor :obj => Object # VALUE type
         | 
| 12 | 
            +
            end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            Parent.commit
         | 
| 15 | 
            +
              # we're done adding attrs and methods, so make.
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            x = Child.new
         | 
| 18 | 
            +
            x.ruby_str = "foo"
         | 
| 19 | 
            +
            x.obj = [1,2,3]
         | 
| 20 | 
            +
            x.c_int = 3
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            p x
         | 
| 23 | 
            +
            # ==> #<Child:0xb7ba96f4 ruby_str="foo", c_int=3, obj=[1, 2, 3]>
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            CShadow.allow_yaml
         | 
| 26 | 
            +
            y x
         | 
| @@ -0,0 +1,80 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            The generated code looks, in part, as follows. Note that CGenerator/CShadow produces quite readable C code. In the Parent.h header file we have:
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              typedef struct Parent_Shadow {
         | 
| 5 | 
            +
                  VALUE self;
         | 
| 6 | 
            +
                  VALUE ruby_str; // String;
         | 
| 7 | 
            +
                  int c_int;
         | 
| 8 | 
            +
              } Parent_Shadow;
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              typedef struct Child_Shadow {
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  /* Parent_Shadow members */
         | 
| 13 | 
            +
                  VALUE self;
         | 
| 14 | 
            +
                  VALUE ruby_str; // String;
         | 
| 15 | 
            +
                  int c_int;
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  VALUE obj; // Object;
         | 
| 18 | 
            +
              } Child_Shadow;
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            Again, members are duplicated, which would be awful if you wanted to manually maintain the code, but who wants to do that :-)
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            In the Parent.c file, we have:
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              void mark_Parent_Shadow(Parent_Shadow *shadow)
         | 
| 25 | 
            +
              {
         | 
| 26 | 
            +
                  rb_gc_mark((void *)shadow->self);
         | 
| 27 | 
            +
                  rb_gc_mark((void *)shadow->ruby_str);
         | 
| 28 | 
            +
              }
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              void mark_Child_Shadow(Child_Shadow *shadow)
         | 
| 31 | 
            +
              {
         | 
| 32 | 
            +
                  rb_gc_mark((void *)shadow->self);
         | 
| 33 | 
            +
                  rb_gc_mark((void *)shadow->ruby_str);
         | 
| 34 | 
            +
                  rb_gc_mark((void *)shadow->obj);
         | 
| 35 | 
            +
              }
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            and similarly for the free functions, persistence functions, etc. The #new method generated by CShadow is where rb_obj_call_init() gets called. Note that initialization of shadow attributes is customizable.
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              VALUE new_module_Child_singleton_method(int argc, VALUE *argv, VALUE self)
         | 
| 40 | 
            +
              {
         | 
| 41 | 
            +
                  VALUE object;
         | 
| 42 | 
            +
                  Child_Shadow *shadow;
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  object = Data_Make_Struct(self,
         | 
| 45 | 
            +
                             Child_Shadow,
         | 
| 46 | 
            +
                             mark_Child_Shadow,
         | 
| 47 | 
            +
                             free_Child_Shadow,
         | 
| 48 | 
            +
                             shadow);
         | 
| 49 | 
            +
                  shadow->self = object;
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  shadow->ruby_str = Qnil;
         | 
| 52 | 
            +
                  shadow->obj = Qnil;
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  rb_obj_call_init(object, argc, argv);
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  return object;
         | 
| 57 | 
            +
              }
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            The #ruby_str= method only needs to be defined for Parent, because, of course, Ruby itself handles inheritance of methods. Note the type checking, which is done for the ruby_str member but not for the obj member.
         | 
| 60 | 
            +
             | 
| 61 | 
            +
              VALUE ruby__str_equals_module_Parent_method(int argc, VALUE *argv, VALUE self)
         | 
| 62 | 
            +
              {
         | 
| 63 | 
            +
                  VALUE arg;
         | 
| 64 | 
            +
                  Parent_Shadow *shadow;
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  rb_scan_args(argc, argv, "1", &arg);
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                  if (!NIL_P(arg) &&
         | 
| 69 | 
            +
                      rb_obj_is_kind_of(arg, module_String) != Qtrue)
         | 
| 70 | 
            +
                    rb_raise(module_TypeError,
         | 
| 71 | 
            +
                             "argument arg declared String but passed %s.",
         | 
| 72 | 
            +
                             STR2CSTR(rb_funcall(
         | 
| 73 | 
            +
                               rb_funcall(arg, ID_type, 0),
         | 
| 74 | 
            +
                               ID_to__s, 0)));
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                  Data_Get_Struct(self, Parent_Shadow, shadow);
         | 
| 77 | 
            +
                  shadow->ruby_str = arg;
         | 
| 78 | 
            +
                  return arg;
         | 
| 79 | 
            +
              }
         | 
| 80 | 
            +
             | 
| @@ -0,0 +1,66 @@ | |
| 1 | 
            +
            require 'cgen/cshadow'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class A
         | 
| 4 | 
            +
              include CShadow
         | 
| 5 | 
            +
              
         | 
| 6 | 
            +
              define_c_method :instance_eval_proc do
         | 
| 7 | 
            +
                c_array_args {
         | 
| 8 | 
            +
                  required :pr
         | 
| 9 | 
            +
                  typecheck :pr => Proc
         | 
| 10 | 
            +
                }
         | 
| 11 | 
            +
                body %{
         | 
| 12 | 
            +
                  printf("instance_eval_proc\\n");
         | 
| 13 | 
            +
                }
         | 
| 14 | 
            +
                returns "rb_iterate(my_instance_eval, shadow->self, call_block, pr)"
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
              
         | 
| 17 | 
            +
              fn = shadow_library_source_file.define :my_instance_eval
         | 
| 18 | 
            +
              fn.instance_eval do
         | 
| 19 | 
            +
                arguments "VALUE obj"
         | 
| 20 | 
            +
                return_type "VALUE"
         | 
| 21 | 
            +
                body %{
         | 
| 22 | 
            +
                  printf("my_instance_eval\\n");
         | 
| 23 | 
            +
                }
         | 
| 24 | 
            +
                returns "rb_obj_instance_eval(0, 0, obj)"
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
              
         | 
| 27 | 
            +
              fn = shadow_library_source_file.define :call_block
         | 
| 28 | 
            +
              fn.instance_eval do
         | 
| 29 | 
            +
                arguments "VALUE arg1", "VALUE block"
         | 
| 30 | 
            +
                return_type "VALUE"
         | 
| 31 | 
            +
                body %{
         | 
| 32 | 
            +
                  printf("call_block\\n");
         | 
| 33 | 
            +
                }
         | 
| 34 | 
            +
                returns "rb_funcall(block, #{declare_symbol :call}, 0)"
         | 
| 35 | 
            +
              end  
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            Dir.chdir "tmp" do
         | 
| 40 | 
            +
              A.commit
         | 
| 41 | 
            +
            end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            a = A.new
         | 
| 44 | 
            +
            pr = proc { "self is %p" % self }
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            p a.instance_eval(&pr)
         | 
| 47 | 
            +
            puts '---'
         | 
| 48 | 
            +
            p a.instance_eval_proc(pr)
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            __END__
         | 
| 51 | 
            +
             | 
| 52 | 
            +
             | 
| 53 | 
            +
             | 
| 54 | 
            +
            static VALUE my_instance_eval(VALUE obj)
         | 
| 55 | 
            +
            {
         | 
| 56 | 
            +
                return rb_obj_instance_eval(0, 0, obj);
         | 
| 57 | 
            +
            }
         | 
| 58 | 
            +
             | 
| 59 | 
            +
            static VALUE call_block(VALUE arg1, VALUE block)
         | 
| 60 | 
            +
            {
         | 
| 61 | 
            +
                return rb_funcall(block, ID_call, 0);
         | 
| 62 | 
            +
            }
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            //...
         | 
| 65 | 
            +
                rb_iterate(my_instance_eval, obj, call_block, pr);
         | 
| 66 | 
            +
             | 
    
        data/examples/ivset.rb
    ADDED
    
    | @@ -0,0 +1,55 @@ | |
| 1 | 
            +
            class Foo
         | 
| 2 | 
            +
              def initialize
         | 
| 3 | 
            +
                @a = 1
         | 
| 4 | 
            +
                @b = 2
         | 
| 5 | 
            +
              end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              def inc_iv
         | 
| 8 | 
            +
                [:@a, :@b].each { |iv|
         | 
| 9 | 
            +
                  eval "#{iv} += 1"
         | 
| 10 | 
            +
                }
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
            end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            require 'cgen/cshadow'
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            class Bar
         | 
| 17 | 
            +
              include CShadow
         | 
| 18 | 
            +
              
         | 
| 19 | 
            +
              def initialize
         | 
| 20 | 
            +
                @a = 1
         | 
| 21 | 
            +
                @b = 2
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
              
         | 
| 24 | 
            +
              def inc_iv
         | 
| 25 | 
            +
                [:@a, :@b].each { |iv|
         | 
| 26 | 
            +
                  iv = iv
         | 
| 27 | 
            +
                  set_iv(iv, get_iv(iv) + 1)
         | 
| 28 | 
            +
                }
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
              
         | 
| 31 | 
            +
              define_method :set_iv do
         | 
| 32 | 
            +
                arguments :attr, :value
         | 
| 33 | 
            +
                body %{
         | 
| 34 | 
            +
                  rb_ivar_set(shadow->self, rb_to_id(attr), value);
         | 
| 35 | 
            +
                }
         | 
| 36 | 
            +
                returns %{shadow->self}
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
              private :set_iv
         | 
| 39 | 
            +
              
         | 
| 40 | 
            +
              define_method :get_iv do
         | 
| 41 | 
            +
                arguments :attr
         | 
| 42 | 
            +
                returns %{rb_ivar_get(shadow->self, rb_to_id(attr))}
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
              private :get_iv
         | 
| 45 | 
            +
              
         | 
| 46 | 
            +
              def inspect
         | 
| 47 | 
            +
                "<Bar: a = #{@a}, b = #{@b}>"
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
            end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
            Bar.commit # write to .c files, make, and require
         | 
| 52 | 
            +
             | 
| 53 | 
            +
            bar = Bar.new
         | 
| 54 | 
            +
            bar.inc_iv
         | 
| 55 | 
            +
            p bar
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            require 'cgen/cshadow'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class MarshalTest
         | 
| 4 | 
            +
              include CShadow
         | 
| 5 | 
            +
              
         | 
| 6 | 
            +
              shadow_attr_accessor :x => Object
         | 
| 7 | 
            +
            end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            Dir.mkdir "tmp" rescue SystemCallError
         | 
| 10 | 
            +
            Dir.chdir "tmp"
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            MarshalTest.commit
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            mt = MarshalTest.new
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            mt.x = "foo"
         | 
| 17 | 
            +
            p mt.x
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            p Marshal.dump mt
         | 
    
        data/examples/matrix.rb
    ADDED
    
    | @@ -0,0 +1,91 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'cgen/cshadow'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            class MyMatrix
         | 
| 6 | 
            +
              include CShadow
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              shadow_attr_reader :rows => "int rows", :cols => "int cols"
         | 
| 9 | 
            +
              shadow_attr :matrix => "double *matrix"
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              define_c_method(:initialize) {
         | 
| 12 | 
            +
                c_array_args {
         | 
| 13 | 
            +
                  required :rows, :cols
         | 
| 14 | 
            +
                  typecheck :rows => Fixnum, :cols => Fixnum
         | 
| 15 | 
            +
                }
         | 
| 16 | 
            +
                declare :size => "int size"
         | 
| 17 | 
            +
                body %{
         | 
| 18 | 
            +
                  shadow->rows = FIX2INT(rows);
         | 
| 19 | 
            +
                  shadow->cols = FIX2INT(cols);
         | 
| 20 | 
            +
                  
         | 
| 21 | 
            +
                  if (shadow->rows <= 0)
         | 
| 22 | 
            +
                    rb_raise(#{declare_class ArgumentError}, "Rows must be positive.");
         | 
| 23 | 
            +
                  if (shadow->cols <= 0)
         | 
| 24 | 
            +
                    rb_raise(#{declare_class ArgumentError}, "Cols must be positive.");
         | 
| 25 | 
            +
                  
         | 
| 26 | 
            +
                  size = shadow->rows * shadow->cols;
         | 
| 27 | 
            +
                  shadow->matrix = ALLOC_N(double, size);
         | 
| 28 | 
            +
                  memset(shadow->matrix, 0, size * sizeof(double));
         | 
| 29 | 
            +
                }
         | 
| 30 | 
            +
              }
         | 
| 31 | 
            +
              
         | 
| 32 | 
            +
              define_c_method(:[]) {
         | 
| 33 | 
            +
                arguments :i, :j
         | 
| 34 | 
            +
                declare :ii => "int ii", :jj => "int jj"
         | 
| 35 | 
            +
                body %{
         | 
| 36 | 
            +
                  ii = NUM2INT(i);
         | 
| 37 | 
            +
                  jj = NUM2INT(j);
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  if (ii < 0 || ii >= shadow->rows)
         | 
| 40 | 
            +
                    rb_raise(#{declare_class IndexError},
         | 
| 41 | 
            +
                             "Row index %d out of range [0, %d]",
         | 
| 42 | 
            +
                             ii, shadow->rows - 1);
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  if (jj < 0 || jj >= shadow->cols)
         | 
| 45 | 
            +
                    rb_raise(#{declare_class IndexError},
         | 
| 46 | 
            +
                             "Column index %d out of range [0, %d]",
         | 
| 47 | 
            +
                             jj, shadow->cols - 1);
         | 
| 48 | 
            +
                }
         | 
| 49 | 
            +
                returns "rb_float_new(shadow->matrix[ii * shadow->cols + jj])"
         | 
| 50 | 
            +
              }
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              define_c_method(:[]=) {
         | 
| 53 | 
            +
                arguments :i, :j, :x
         | 
| 54 | 
            +
                declare :ii => "int ii", :jj => "int jj", :xx => "double xx"
         | 
| 55 | 
            +
                body %{
         | 
| 56 | 
            +
                  ii = NUM2INT(i);
         | 
| 57 | 
            +
                  jj = NUM2INT(j);
         | 
| 58 | 
            +
                  xx = NUM2DBL(x);
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  if (ii < 0 || ii >= shadow->rows)
         | 
| 61 | 
            +
                    rb_raise(#{declare_class IndexError},
         | 
| 62 | 
            +
                             "Row index %d out of range 0..%d",
         | 
| 63 | 
            +
                             ii, shadow->rows - 1);
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                  if (jj < 0 || jj >= shadow->cols)
         | 
| 66 | 
            +
                    rb_raise(#{declare_class IndexError},
         | 
| 67 | 
            +
                             "Column index %d out of range 0..%d",
         | 
| 68 | 
            +
                             jj, shadow->cols - 1);
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  shadow->matrix[ii * shadow->cols + jj] = xx;
         | 
| 71 | 
            +
                }
         | 
| 72 | 
            +
                returns "x"
         | 
| 73 | 
            +
              }
         | 
| 74 | 
            +
            end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
            require 'ftools'
         | 
| 77 | 
            +
            dir = File.join("tmp", RUBY_VERSION)
         | 
| 78 | 
            +
            File.mkpath dir
         | 
| 79 | 
            +
            Dir.chdir dir
         | 
| 80 | 
            +
             | 
| 81 | 
            +
            MyMatrix.commit
         | 
| 82 | 
            +
             | 
| 83 | 
            +
            m = MyMatrix.new 5, 2
         | 
| 84 | 
            +
            m[3,1] = 8.2e+13
         | 
| 85 | 
            +
            puts m[3,1]
         | 
| 86 | 
            +
            puts m[3,0]
         | 
| 87 | 
            +
            begin
         | 
| 88 | 
            +
              puts m[3,2]
         | 
| 89 | 
            +
            rescue IndexError
         | 
| 90 | 
            +
              puts "Caught an IndexError: m[3,2] is out of range."
         | 
| 91 | 
            +
            end
         | 
| @@ -0,0 +1,87 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # This example shows how to factor out definitions into a module. The
         | 
| 4 | 
            +
            # only additional library code needed is the following:
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module ModuleMethodSaver
         | 
| 7 | 
            +
              def method_missing(meth, *args, &block)
         | 
| 8 | 
            +
                @saved ||= []
         | 
| 9 | 
            +
                @saved << [meth, args, block]
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
              
         | 
| 12 | 
            +
              def included(m)
         | 
| 13 | 
            +
                if @saved
         | 
| 14 | 
            +
                  @saved.each do |meth, args, block|
         | 
| 15 | 
            +
                    m.send(meth, *args, &block)
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
             | 
| 22 | 
            +
            require 'cgen/cshadow'
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            module ComplexStuff
         | 
| 25 | 
            +
              extend ModuleMethodSaver
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              shadow_attr_accessor :re => "double re", :im => "double im"
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              def initialize re, im
         | 
| 30 | 
            +
                self.re = re
         | 
| 31 | 
            +
                self.im = im
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              define_c_method(:abs) {
         | 
| 35 | 
            +
                include "<math.h>"
         | 
| 36 | 
            +
                returns "rb_float_new(sqrt(pow(shadow->re, 2) + pow(shadow->im, 2)))"
         | 
| 37 | 
            +
              }
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              define_c_method(:mul!) {
         | 
| 40 | 
            +
                arguments :other
         | 
| 41 | 
            +
                declare :other_shadow => "MyComplex_Shadow *other_shadow"
         | 
| 42 | 
            +
                declare :new_re => "double new_re", :new_im => "double new_im"
         | 
| 43 | 
            +
                body %{
         | 
| 44 | 
            +
                  switch (TYPE(other)) {
         | 
| 45 | 
            +
                    case T_FIXNUM:  shadow->re *= FIX2INT(other);
         | 
| 46 | 
            +
                                    shadow->im *= FIX2INT(other); break;
         | 
| 47 | 
            +
                    case T_FLOAT:   shadow->re *= NUM2DBL(other);
         | 
| 48 | 
            +
                                    shadow->im *= NUM2DBL(other); break;
         | 
| 49 | 
            +
                    default:
         | 
| 50 | 
            +
                      if (rb_obj_is_kind_of(other, #{declare_class MyComplex}) ==
         | 
| 51 | 
            +
                          Qtrue) {
         | 
| 52 | 
            +
                        Data_Get_Struct(other, MyComplex_Shadow, other_shadow);
         | 
| 53 | 
            +
                        new_re = shadow->re * other_shadow->re -
         | 
| 54 | 
            +
                                 shadow->im * other_shadow->im;
         | 
| 55 | 
            +
                        new_im = shadow->re * other_shadow->im +
         | 
| 56 | 
            +
                                 shadow->im * other_shadow->re;
         | 
| 57 | 
            +
                        shadow->re = new_re;
         | 
| 58 | 
            +
                        shadow->im = new_im;
         | 
| 59 | 
            +
                      }
         | 
| 60 | 
            +
                      else
         | 
| 61 | 
            +
                        rb_raise(#{declare_class ArgumentError},
         | 
| 62 | 
            +
                                 "Argument to mul! is not numeric.");
         | 
| 63 | 
            +
                  }
         | 
| 64 | 
            +
                }
         | 
| 65 | 
            +
                returns "self"
         | 
| 66 | 
            +
              }
         | 
| 67 | 
            +
            end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
            class MyComplex < Numeric
         | 
| 70 | 
            +
              include CShadow
         | 
| 71 | 
            +
              include ComplexStuff
         | 
| 72 | 
            +
            end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
            require 'ftools'
         | 
| 75 | 
            +
            dir = File.join("tmp", RUBY_VERSION)
         | 
| 76 | 
            +
            File.mkpath dir
         | 
| 77 | 
            +
            Dir.chdir dir
         | 
| 78 | 
            +
             | 
| 79 | 
            +
            MyComplex.commit
         | 
| 80 | 
            +
             | 
| 81 | 
            +
            z = MyComplex.new 5, 1.3
         | 
| 82 | 
            +
            puts z.abs
         | 
| 83 | 
            +
            z.mul! 10
         | 
| 84 | 
            +
            p [z.re, z.im]
         | 
| 85 | 
            +
            w = MyComplex.new 7.9, -1.2
         | 
| 86 | 
            +
            z.mul! w
         | 
| 87 | 
            +
            p [z.re, z.im]
         | 
    
        data/examples/objattr.rb
    ADDED
    
    | @@ -0,0 +1,46 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'cgen/cshadow'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            SAME_LIBRARY = true
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            class A
         | 
| 8 | 
            +
              include CShadow
         | 
| 9 | 
            +
              shadow_attr_accessor :obj => Object, :sym => Symbol
         | 
| 10 | 
            +
            end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            class B
         | 
| 13 | 
            +
              include CShadow
         | 
| 14 | 
            +
              
         | 
| 15 | 
            +
              if SAME_LIBRARY
         | 
| 16 | 
            +
                shadow_library A                # in the same lib as A
         | 
| 17 | 
            +
                shadow_library_file 'B'         # but in a different file
         | 
| 18 | 
            +
              else  
         | 
| 19 | 
            +
                # different lib, but connected with a '#include'
         | 
| 20 | 
            +
                shadow_library_include_file.include '../A/A.h'
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
              
         | 
| 23 | 
            +
              shadow_attr_accessor :a => [A]
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              def initialize
         | 
| 26 | 
            +
                self.a = A.new
         | 
| 27 | 
            +
                self.a.sym = :something
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
            end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            require 'ftools'
         | 
| 32 | 
            +
            dir = File.join("tmp", RUBY_VERSION)
         | 
| 33 | 
            +
            File.mkpath dir
         | 
| 34 | 
            +
            Dir.chdir dir
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            A.commit
         | 
| 37 | 
            +
            unless SAME_LIBRARY
         | 
| 38 | 
            +
              B.commit
         | 
| 39 | 
            +
            end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            p B.new.a.sym
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            A.shadow_library.make 'distclean'
         | 
| 44 | 
            +
            unless SAME_LIBRARY
         | 
| 45 | 
            +
              B.shadow_library.make 'distclean'
         | 
| 46 | 
            +
            end
         |