summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--include/mruby.h8
-rw-r--r--mrbgems/mruby-array-ext/mrblib/array.rb39
-rw-r--r--mrbgems/mruby-array-ext/test/array.rb9
-rw-r--r--mrbgems/mruby-string-utf8/src/string.c5
-rw-r--r--mrbgems/mruby-string-utf8/test/string.rb49
-rw-r--r--mrbgems/mruby-struct/src/struct.c5
-rw-r--r--src/dump.c6
-rw-r--r--src/parse.y10
-rw-r--r--test/t/syntax.rb11
10 files changed, 107 insertions, 36 deletions
diff --git a/AUTHORS b/AUTHORS
index 3791ad723..555cf7743 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -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