From 6c284ec31f470681e333bac431d3a074fc1d27fd Mon Sep 17 00:00:00 2001 From: skandhas Date: Fri, 15 Mar 2013 11:28:01 +0800 Subject: add mrbgem: mrb-array-ext --- mrbgems/mruby-array-ext/mrbgem.rake | 4 + mrbgems/mruby-array-ext/src/array.c | 140 ++++++++++++++++++++++++++++++++++ mrbgems/mruby-array-ext/test/array.rb | 30 ++++++++ 3 files changed, 174 insertions(+) create mode 100644 mrbgems/mruby-array-ext/mrbgem.rake create mode 100644 mrbgems/mruby-array-ext/src/array.c create mode 100644 mrbgems/mruby-array-ext/test/array.rb diff --git a/mrbgems/mruby-array-ext/mrbgem.rake b/mrbgems/mruby-array-ext/mrbgem.rake new file mode 100644 index 000000000..38e0ad267 --- /dev/null +++ b/mrbgems/mruby-array-ext/mrbgem.rake @@ -0,0 +1,4 @@ +MRuby::Gem::Specification.new('mruby-array-ext') do |spec| + spec.license = 'MIT' + spec.authors = 'mruby developers' +end diff --git a/mrbgems/mruby-array-ext/src/array.c b/mrbgems/mruby-array-ext/src/array.c new file mode 100644 index 000000000..71516fdf7 --- /dev/null +++ b/mrbgems/mruby-array-ext/src/array.c @@ -0,0 +1,140 @@ +#include "mruby.h" +#include "mruby/value.h" +#include "mruby/array.h" + +/* + * call-seq: + * Array.try_convert(obj) -> array or nil + * + * Try to convert obj into an array, using +to_ary+ method. + * Returns converted array or +nil+ if obj cannot be converted + * for any reason. This method can be used to check if an argument is an + * array. + * + * Array.try_convert([1]) #=> [1] + * Array.try_convert("1") #=> nil + * + * if tmp = Array.try_convert(arg) + * # the argument is an array + * elsif tmp = String.try_convert(arg) + * # the argument is a string + * end + * + */ + +static mrb_value +mrb_ary_try_convert(mrb_state *mrb, mrb_value self) +{ + mrb_value ary; + + mrb_get_args(mrb, "o", &ary); + return mrb_check_array_type(mrb, ary); +} + +/* + * call-seq: + * ary.assoc(obj) -> new_ary or nil + * + * Searches through an array whose elements are also arrays + * comparing _obj_ with the first element of each contained array + * using obj.==. + * Returns the first contained array that matches (that + * is, the first associated array), + * or +nil+ if no match is found. + * See also Array#rassoc. + * + * s1 = [ "colors", "red", "blue", "green" ] + * s2 = [ "letters", "a", "b", "c" ] + * s3 = "foo" + * a = [ s1, s2, s3 ] + * a.assoc("letters") #=> [ "letters", "a", "b", "c" ] + * a.assoc("foo") #=> nil + */ + +static mrb_value +mrb_ary_assoc(mrb_state *mrb, mrb_value ary) +{ + mrb_int i; + mrb_value v, k; + + mrb_get_args(mrb, "o", &k); + + for (i = 0; i < RARRAY_LEN(ary); ++i) { + v = mrb_check_array_type(mrb, RARRAY_PTR(ary)[i]); + if (!mrb_nil_p(v) && RARRAY_LEN(v) > 0 && + mrb_equal(mrb, RARRAY_PTR(v)[0], k)) + return v; + } + return mrb_nil_value(); +} + +/* + * call-seq: + * ary.rassoc(obj) -> new_ary or nil + * + * Searches through the array whose elements are also arrays. Compares + * _obj_ with the second element of each contained array using + * ==. Returns the first contained array that matches. See + * also Array#assoc. + * + * a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ] + * a.rassoc("two") #=> [2, "two"] + * a.rassoc("four") #=> nil + */ + +static mrb_value +mrb_ary_rassoc(mrb_state *mrb, mrb_value ary) +{ + mrb_int i; + mrb_value v, value; + + mrb_get_args(mrb, "o", &value); + + for (i = 0; i < RARRAY_LEN(ary); ++i) { + v = RARRAY_PTR(ary)[i]; + if (mrb_type(v) == MRB_TT_ARRAY && + RARRAY_LEN(v) > 1 && + mrb_equal(mrb, RARRAY_PTR(v)[1], value)) + return v; + } + return mrb_nil_value(); +} + +/* + * call-seq: + * ary.at(index) -> obj or nil + * + * Returns the element at _index_. A + * negative index counts from the end of +self+. Returns +nil+ + * if the index is out of range. See also Array#[]. + * + * a = [ "a", "b", "c", "d", "e" ] + * a.at(0) #=> "a" + * a.at(-1) #=> "e" + */ + +static mrb_value +mrb_ary_at(mrb_state *mrb, mrb_value ary) +{ + mrb_int pos; + mrb_get_args(mrb, "i", &pos); + + return mrb_ary_entry(ary, pos); +} + +void +mrb_mruby_array_ext_gem_init(mrb_state* mrb) +{ + struct RClass * a = mrb->array_class; + + mrb_define_class_method(mrb, a, "try_convert", mrb_ary_try_convert, ARGS_REQ(1)); + + mrb_define_method(mrb, a, "assoc", mrb_ary_assoc, ARGS_REQ(1)); + mrb_define_method(mrb, a, "at", mrb_ary_at, ARGS_REQ(1)); + mrb_define_method(mrb, a, "rassoc", mrb_ary_rassoc, ARGS_REQ(1)); +} + +void +mrb_mruby_array_ext_gem_final(mrb_state* mrb) +{ +} diff --git a/mrbgems/mruby-array-ext/test/array.rb b/mrbgems/mruby-array-ext/test/array.rb new file mode 100644 index 000000000..905606c9d --- /dev/null +++ b/mrbgems/mruby-array-ext/test/array.rb @@ -0,0 +1,30 @@ +## +# Array(Ext) Test + +assert("Array::try_convert") do + Array.try_convert([1]) == [1] and + Array.try_convert("1").nil? +end + +assert("Array#assoc") do + s1 = [ "colors", "red", "blue", "green" ] + s2 = [ "letters", "a", "b", "c" ] + s3 = "foo" + a = [ s1, s2, s3 ] + + a.assoc("letters") == [ "letters", "a", "b", "c" ] and + a.assoc("foo").nil? +end + +assert("Array#at") do + a = [ "a", "b", "c", "d", "e" ] + a.at(0) == "a" and a.at(-1) == "e" +end + +assert("Array::rassoc") do + a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ] + + a.rassoc("two") == [2, "two"] and + a.rassoc("four").nil? +end + -- cgit v1.2.3 From 59d33146e56d9dcc67592398482b617693a7c77c Mon Sep 17 00:00:00 2001 From: skandhas Date: Fri, 15 Mar 2013 11:29:48 +0800 Subject: update build_config.rb --- build_config.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build_config.rb b/build_config.rb index 7ca020527..4ed295c38 100644 --- a/build_config.rb +++ b/build_config.rb @@ -29,6 +29,9 @@ MRuby::Build.new do |conf| # Use extensional Numeric class conf.gem "#{root}/mrbgems/mruby-numeric-ext" + # Use extensional Array class + conf.gem "#{root}/mrbgems/mruby-array-ext" + # Generate binaries # conf.bins = %w(mrbc mruby mirb) -- cgit v1.2.3 From e6ab9237cc72469dfc6dd3279ce31be4495ac011 Mon Sep 17 00:00:00 2001 From: skandhas Date: Fri, 15 Mar 2013 11:41:49 +0800 Subject: rename method --- mrbgems/mruby-array-ext/src/array.c | 4 ++-- mrbgems/mruby-array-ext/test/array.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mrbgems/mruby-array-ext/src/array.c b/mrbgems/mruby-array-ext/src/array.c index 71516fdf7..7d7425efd 100644 --- a/mrbgems/mruby-array-ext/src/array.c +++ b/mrbgems/mruby-array-ext/src/array.c @@ -23,7 +23,7 @@ */ static mrb_value -mrb_ary_try_convert(mrb_state *mrb, mrb_value self) +mrb_ary_s_try_convert(mrb_state *mrb, mrb_value self) { mrb_value ary; @@ -127,7 +127,7 @@ mrb_mruby_array_ext_gem_init(mrb_state* mrb) { struct RClass * a = mrb->array_class; - mrb_define_class_method(mrb, a, "try_convert", mrb_ary_try_convert, ARGS_REQ(1)); + mrb_define_class_method(mrb, a, "try_convert", mrb_ary_s_try_convert, ARGS_REQ(1)); mrb_define_method(mrb, a, "assoc", mrb_ary_assoc, ARGS_REQ(1)); mrb_define_method(mrb, a, "at", mrb_ary_at, ARGS_REQ(1)); diff --git a/mrbgems/mruby-array-ext/test/array.rb b/mrbgems/mruby-array-ext/test/array.rb index 905606c9d..36da6bb17 100644 --- a/mrbgems/mruby-array-ext/test/array.rb +++ b/mrbgems/mruby-array-ext/test/array.rb @@ -21,7 +21,7 @@ assert("Array#at") do a.at(0) == "a" and a.at(-1) == "e" end -assert("Array::rassoc") do +assert("Array#rassoc") do a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ] a.rassoc("two") == [2, "two"] and -- cgit v1.2.3