diff options
| -rw-r--r-- | AUTHORS | 1 | ||||
| -rw-r--r-- | include/mruby.h | 8 | ||||
| -rw-r--r-- | mrbgems/mruby-array-ext/mrblib/array.rb | 39 | ||||
| -rw-r--r-- | mrbgems/mruby-array-ext/test/array.rb | 9 | ||||
| -rw-r--r-- | mrbgems/mruby-string-utf8/src/string.c | 5 | ||||
| -rw-r--r-- | mrbgems/mruby-string-utf8/test/string.rb | 49 | ||||
| -rw-r--r-- | mrbgems/mruby-struct/src/struct.c | 5 | ||||
| -rw-r--r-- | src/dump.c | 6 | ||||
| -rw-r--r-- | src/parse.y | 10 | ||||
| -rw-r--r-- | test/t/syntax.rb | 11 |
10 files changed, 107 insertions, 36 deletions
@@ -19,3 +19,4 @@ Original Authors "mruby developers" are: Yuichi Nishiwaki Tatsuhiko Kubo Takeshi Watanabe + Yuki Kurihara diff --git a/include/mruby.h b/include/mruby.h index af1fc9894..b74b1e466 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -57,14 +57,14 @@ typedef struct { struct RProc *proc; mrb_value *stackent; int nregs; - int argc; + int ridx; + int eidx; + struct REnv *env; mrb_code *pc; /* return address */ mrb_code *err; /* error position */ + int argc; int acc; struct RClass *target_class; - int ridx; - int eidx; - struct REnv *env; } mrb_callinfo; enum mrb_fiber_state { diff --git a/mrbgems/mruby-array-ext/mrblib/array.rb b/mrbgems/mruby-array-ext/mrblib/array.rb index 7f48811f1..6c47235fe 100644 --- a/mrbgems/mruby-array-ext/mrblib/array.rb +++ b/mrbgems/mruby-array-ext/mrblib/array.rb @@ -1,7 +1,8 @@ class Array ## # call-seq: - # ary.uniq! -> ary or nil + # ary.uniq! -> ary or nil + # ary.uniq! { |item| ... } -> ary or nil # # Removes duplicate elements from +self+. # Returns <code>nil</code> if no changes are made (that is, no @@ -11,13 +12,27 @@ class Array # a.uniq! #=> ["a", "b", "c"] # b = [ "a", "b", "c" ] # b.uniq! #=> nil + # c = [["student","sam"], ["student","george"], ["teacher","matz"]] + # c.uniq! { |s| s.first } # => [["student", "sam"], ["teacher", "matz"]] # - def uniq! + def uniq!(&block) ary = self.dup result = [] - while ary.size > 0 - result << ary.shift - ary.delete(result.last) + if block + hash = {} + while ary.size > 0 + val = ary.shift + key = block.call(val) + hash[key] = val unless hash.has_key?(key) + end + hash.each_value do |value| + result << value + end + else + while ary.size > 0 + result << ary.shift + ary.delete(result.last) + end end if result.size == self.size nil @@ -28,16 +43,24 @@ class Array ## # call-seq: - # ary.uniq -> new_ary + # ary.uniq -> new_ary + # ary.uniq { |item| ... } -> new_ary # # Returns a new array by removing duplicate values in +self+. # # a = [ "a", "a", "b", "b", "c" ] # a.uniq #=> ["a", "b", "c"] # - def uniq + # b = [["student","sam"], ["student","george"], ["teacher","matz"]] + # b.uniq { |s| s.first } # => [["student", "sam"], ["teacher", "matz"]] + # + def uniq(&block) ary = self.dup - ary.uniq! + if block + ary.uniq!(&block) + else + ary.uniq! + end ary end diff --git a/mrbgems/mruby-array-ext/test/array.rb b/mrbgems/mruby-array-ext/test/array.rb index 9a0f25f9a..d157a5b4d 100644 --- a/mrbgems/mruby-array-ext/test/array.rb +++ b/mrbgems/mruby-array-ext/test/array.rb @@ -36,12 +36,21 @@ assert("Array#uniq!") do b = [ "a", "b", "c" ] assert_nil b.uniq! + + c = [["student","sam"], ["student","george"], ["teacher","matz"]] + assert_equal [["student", "sam"], ["teacher", "matz"]], c.uniq! { |s| s.first } + + d = [["student","sam"], ["teacher","matz"]] + assert_nil d.uniq! { |s| s.first } end assert("Array#uniq") do a = [1, 2, 3, 1] assert_equal [1, 2, 3], a.uniq assert_equal [1, 2, 3, 1], a + + b = [["student","sam"], ["student","george"], ["teacher","matz"]] + assert_equal [["student", "sam"], ["teacher", "matz"]], b.uniq { |s| s.first } end assert("Array#-") do diff --git a/mrbgems/mruby-string-utf8/src/string.c b/mrbgems/mruby-string-utf8/src/string.c index 3d5d44c77..45dd66eec 100644 --- a/mrbgems/mruby-string-utf8/src/string.c +++ b/mrbgems/mruby-string-utf8/src/string.c @@ -636,7 +636,8 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str) while (ptr < eptr && (end = mrb_memsearch(sptr, slen, ptr, eptr - ptr)) >= 0) { - mrb_ary_push(mrb, result, str_subseq(mrb, str, ptr - temp, end)); + // mrb_ary_push(mrb, result, str_subseq(mrb, str, ptr - temp, end)); + mrb_ary_push(mrb, result, mrb_str_new(mrb, ptr, end)); mrb_gc_arena_restore(mrb, ai); ptr += end + slen; if (lim_p && lim <= ++i) break; @@ -652,7 +653,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str) tmp = mrb_str_new_lit(mrb, ""); } else { - tmp = str_subseq(mrb, str, beg, RSTRING_LEN(str)-beg); + tmp = mrb_str_new(mrb, RSTRING_PTR(str)+beg, RSTRING_LEN(str)-beg); } mrb_ary_push(mrb, result, tmp); } diff --git a/mrbgems/mruby-string-utf8/test/string.rb b/mrbgems/mruby-string-utf8/test/string.rb index 939ac24bb..ce99fba47 100644 --- a/mrbgems/mruby-string-utf8/test/string.rb +++ b/mrbgems/mruby-string-utf8/test/string.rb @@ -1,29 +1,30 @@ +# -*- coding: utf-8 -*- ## # String(utf8) Test assert('String#[]') do - assert_equal "ち", "こんにちわ世界"[3] - assert_equal nil, "こんにちわ世界"[20] - assert_equal "世", "こんにちわ世界"[-2] - assert_equal "世界", "こんにちわ世界"[-2..-1] - assert_equal "んに", "こんにちわ世界"[1,2] - assert_equal "世", "こんにちわ世界"["世"] + assert_equal "ち", "こんにちは世界"[3] + assert_equal nil, "こんにちは世界"[20] + assert_equal "世", "こんにちは世界"[-2] + assert_equal "世界", "こんにちは世界"[-2..-1] + assert_equal "んに", "こんにちは世界"[1,2] + assert_equal "世", "こんにちは世界"["世"] end assert('String#reverse', '15.2.10.5.29') do - a = 'こんにちわ世界!' + a = 'こんにちは世界!' a.reverse - assert_equal 'こんにちわ世界!', a - assert_equal '!界世わちにんこ', 'こんにちわ世界!'.reverse + assert_equal 'こんにちは世界!', a + assert_equal '!界世はちにんこ', 'こんにちは世界!'.reverse end assert('String#reverse!', '15.2.10.5.30') do - a = 'こんにちわ世界!' + a = 'こんにちは世界!' a.reverse! - assert_equal '!界世わちにんこ', a - assert_equal '!界世わちにんこ', 'こんにちわ世界!'.reverse! + assert_equal '!界世はちにんこ', a + assert_equal '!界世はちにんこ', 'こんにちは世界!'.reverse! end assert('Invalid sequence') do @@ -32,16 +33,36 @@ assert('Invalid sequence') do end assert('String#size') do - str = 'こんにちわ世界!' + str = 'こんにちは世界!' assert_equal 8, str.size assert_not_equal str.bytesize, str.size assert_equal 2, str[1, 2].size end assert('String#index') do - str = "こんにちわ世界!\nこんにちわ世界!" + str = "こんにちは世界!\nこんにちは世界!" assert_nil str.index('さ') assert_equal 3, str.index('ち') assert_equal 12, str.index('ち', 10) assert_equal nil, str.index("さ") end + +assert('String#ord') do + got = "こんにちは世界!".split('').map {|x| x.ord} + expect = [0x3053,0x3093,0x306b,0x3061,0x306f,0x4e16,0x754c,0x21] + assert_equal expect, got +end + +assert('String#split') do + got = "こんにちは世界!".split('') + assert_equal ['こ', 'ん', 'に', 'ち', 'は', '世', '界', '!'], got + got = "こんにちは世界!".split('に') + assert_equal ['こん', 'ちは世界!'], got +end + +assert('String#rindex') do + str = "こんにちは世界!\nこんにちは世界!" + assert_nil str.index('さ') + assert_equal 12, str.rindex('ち') + assert_equal 3, str.rindex('ち', 10) +end diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c index 4f4c3533e..6932bb372 100644 --- a/mrbgems/mruby-struct/src/struct.c +++ b/mrbgems/mruby-struct/src/struct.c @@ -12,9 +12,8 @@ #include "mruby/class.h" #include "mruby/variable.h" -#define RSTRUCT_ARY(st) mrb_ary_ptr(st) -#define RSTRUCT_LEN(st) RSTRUCT_ARY(st)->len -#define RSTRUCT_PTR(st) RSTRUCT_ARY(st)->ptr +#define RSTRUCT_LEN(st) RARRAY_LEN(st) +#define RSTRUCT_PTR(st) RARRAY_PTR(st) static struct RClass * struct_class(mrb_state *mrb) diff --git a/src/dump.c b/src/dump.c index bdfa0787f..2691aab3d 100644 --- a/src/dump.c +++ b/src/dump.c @@ -722,11 +722,11 @@ is_debug_info_defined(mrb_irep *irep) { size_t i; - if (!irep->debug_info) return 0; + if (!irep->debug_info) return FALSE; for (i=0; i<irep->rlen; i++) { - if (!is_debug_info_defined(irep->reps[i])) return 0; + if (!is_debug_info_defined(irep->reps[i])) return FALSE; } - return 1; + return TRUE; } static int diff --git a/src/parse.y b/src/parse.y index 345ac5756..053b5f3e9 100644 --- a/src/parse.y +++ b/src/parse.y @@ -2039,9 +2039,15 @@ primary : literal p->cmdarg_stack = $<stack>1; $$ = $3; } - | tLPAREN_ARG expr {p->lstate = EXPR_ENDARG;} rparen + | tLPAREN_ARG { - $$ = $2; + $<stack>1 = p->cmdarg_stack; + p->cmdarg_stack = 0; + } + expr {p->lstate = EXPR_ENDARG;} rparen + { + p->cmdarg_stack = $<stack>1; + $$ = $3; } | tLPAREN_ARG {p->lstate = EXPR_ENDARG;} rparen { diff --git a/test/t/syntax.rb b/test/t/syntax.rb index fac73aa7b..d761b1991 100644 --- a/test/t/syntax.rb +++ b/test/t/syntax.rb @@ -254,3 +254,14 @@ assert('External command execution.') do end true end + +assert('parenthesed do-block in cmdarg') do + class ParenDoBlockCmdArg + def test(block) + block.call + end + end + x = ParenDoBlockCmdArg.new + result = x.test (proc do :ok; end) + assert_equal :ok, result +end |
