summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2014-04-26 01:53:15 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2014-04-26 01:53:15 +0900
commit2202e412ea6ac44a5bcdaa2640fda0b7485437ca (patch)
tree3e217007696283ad64188ae979a1c0de33a0d947
parent44ec41a7724ef3591e9d4033655fa12e79b9ff2b (diff)
parentb8e5cb71fe4b7e5377facf23ecebd0dd4bc4d1ab (diff)
downloadmruby-2202e412ea6ac44a5bcdaa2640fda0b7485437ca.tar.gz
mruby-2202e412ea6ac44a5bcdaa2640fda0b7485437ca.zip
Merge branch 'master' of github.com:mruby/mruby
-rw-r--r--include/mruby/range.h4
-rw-r--r--mrbgems/mruby-array-ext/mrblib/array.rb30
-rw-r--r--mrbgems/mruby-array-ext/test/array.rb14
-rw-r--r--mrbgems/mruby-eval/src/eval.c63
-rw-r--r--mrbgems/mruby-eval/test/eval.rb7
-rw-r--r--mrbgems/mruby-hash-ext/src/hash-ext.c3
-rw-r--r--mrbgems/mruby-object-ext/src/object.c2
-rw-r--r--mrbgems/mruby-sprintf/src/sprintf.c2
-rw-r--r--mrbgems/mruby-string-ext/src/string.c4
-rw-r--r--mrbgems/mruby-string-utf8/src/string.c4
-rw-r--r--mrbgems/mruby-struct/src/struct.c4
-rw-r--r--mrblib/array.rb7
-rw-r--r--src/codegen.c4
-rw-r--r--src/error.c6
-rw-r--r--src/parse.y2
-rw-r--r--src/range.c4
-rw-r--r--src/vm.c2
17 files changed, 133 insertions, 29 deletions
diff --git a/include/mruby/range.h b/include/mruby/range.h
index 78ddf32a3..828ec2691 100644
--- a/include/mruby/range.h
+++ b/include/mruby/range.h
@@ -19,13 +19,13 @@ typedef struct mrb_range_edges {
struct RRange {
MRB_OBJECT_HEADER;
mrb_range_edges *edges;
- int excl;
+ mrb_bool excl : 1;
};
#define mrb_range_ptr(v) ((struct RRange*)(mrb_ptr(v)))
#define mrb_range_value(p) mrb_obj_value((void*)(p))
-mrb_value mrb_range_new(mrb_state*, mrb_value, mrb_value, int);
+mrb_value mrb_range_new(mrb_state*, mrb_value, mrb_value, mrb_bool);
mrb_bool mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len);
#if defined(__cplusplus)
diff --git a/mrbgems/mruby-array-ext/mrblib/array.rb b/mrbgems/mruby-array-ext/mrblib/array.rb
index 67f7e51a7..9ef7eb166 100644
--- a/mrbgems/mruby-array-ext/mrblib/array.rb
+++ b/mrbgems/mruby-array-ext/mrblib/array.rb
@@ -627,4 +627,34 @@ class Array
end
self
end
+
+ ##
+ # call-seq:
+ # ary.keep_if { |item| block } -> ary
+ # ary.keep_if -> Enumerator
+ #
+ # Deletes every element of +self+ for which the given block evaluates to
+ # +false+.
+ #
+ # See also Array#select!
+ #
+ # If no block is given, an Enumerator is returned instead.
+ #
+ # a = [1, 2, 3, 4, 5]
+ # a.keep_if { |val| val > 3 } #=> [4, 5]
+
+ def keep_if(&block)
+ return to_enum :keep_if unless block_given?
+
+ idx = 0
+ len = self.size
+ while idx < self.size do
+ if block.call(self[idx])
+ idx += 1
+ else
+ self.delete_at(idx)
+ end
+ end
+ self
+ end
end
diff --git a/mrbgems/mruby-array-ext/test/array.rb b/mrbgems/mruby-array-ext/test/array.rb
index 47ffa00cf..c76423522 100644
--- a/mrbgems/mruby-array-ext/test/array.rb
+++ b/mrbgems/mruby-array-ext/test/array.rb
@@ -252,3 +252,17 @@ assert("Array#delete_if") do
a = [ 1, 2, 3, 4, 5 ]
assert_equal [1, 2, 3], a.delete_if { |val| val > 3 }
end
+
+assert("Array#keep_if") do
+ a = [1, 2, 3, 4, 5]
+ assert_equal [1, 2, 3, 4, 5], a.keep_if { true }
+ assert_equal [1, 2, 3, 4, 5], a
+
+ a = [1, 2, 3, 4, 5]
+ assert_equal [], a.keep_if { false }
+ assert_equal [], a
+
+ a = [1, 2, 3, 4, 5]
+ assert_equal [4, 5], a.keep_if { |val| val > 3 }
+ assert_equal [4, 5], a
+end
diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c
index c935f5e2f..710ccbab6 100644
--- a/mrbgems/mruby-eval/src/eval.c
+++ b/mrbgems/mruby-eval/src/eval.c
@@ -1,20 +1,75 @@
#include "mruby.h"
#include "mruby/compile.h"
+static struct RProc*
+create_proc_from_string(mrb_state *mrb, char *s, int len, mrb_value binding, char *file, mrb_int line)
+{
+ mrbc_context *cxt;
+ struct mrb_parser_state *p;
+ struct RProc *proc;
+
+ if (!mrb_nil_p(binding)) {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "Binding of eval must be nil.");
+ }
+
+ cxt = mrbc_context_new(mrb);
+ cxt->lineno = line;
+ if (file) {
+ mrbc_filename(mrb, cxt, file);
+ }
+
+ p = mrb_parser_new(mrb);
+ p->s = s;
+ p->send = s + len;
+ mrb_parser_parse(p, cxt);
+
+ if (0 < p->nerr) {
+ /* parse error */
+ char buf[256];
+ int n;
+ n = snprintf(buf, sizeof(buf), "line %d: %s\n", p->error_buffer[0].lineno, p->error_buffer[0].message);
+ mrb_parser_free(p);
+ mrbc_context_free(mrb, cxt);
+ mrb_exc_raise(mrb, mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, n));
+ }
+
+ proc = mrb_generate_code(mrb, p);
+
+ mrb_parser_free(p);
+ mrbc_context_free(mrb, cxt);
+
+ if (proc == NULL) {
+ /* codegen error */
+ mrb_raise(mrb, E_SCRIPT_ERROR, "codegen error");
+ }
+
+ return proc;
+}
+
static mrb_value
f_eval(mrb_state *mrb, mrb_value self)
{
char *s;
- int len;
+ mrb_int len;
+ mrb_value binding = mrb_nil_value();
+ char *file = NULL;
+ mrb_int line = 1;
+ mrb_value ret;
+
+ mrb_get_args(mrb, "s|ozi", &s, &len, &binding, &file, &line);
+
+ ret = mrb_toplevel_run(mrb, create_proc_from_string(mrb, s, len, binding, file, line));
+ if (mrb->exc) {
+ mrb_exc_raise(mrb, mrb_obj_value(mrb->exc));
+ }
- mrb_get_args(mrb, "s", &s, &len);
- return mrb_load_nstring(mrb, s, len);
+ return ret;
}
void
mrb_mruby_eval_gem_init(mrb_state* mrb)
{
- mrb_define_class_method(mrb, mrb->kernel_module, "eval", f_eval, MRB_ARGS_REQ(1));
+ mrb_define_class_method(mrb, mrb->kernel_module, "eval", f_eval, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(3));
}
void
diff --git a/mrbgems/mruby-eval/test/eval.rb b/mrbgems/mruby-eval/test/eval.rb
index 9c9186a0c..fe1de2978 100644
--- a/mrbgems/mruby-eval/test/eval.rb
+++ b/mrbgems/mruby-eval/test/eval.rb
@@ -6,3 +6,10 @@ end
assert('eval') do
assert_equal(10) { eval '1 * 10' }
end
+
+assert('rest arguments of eval') do
+ assert_raise(ArgumentError) { Kernel.eval('0', 0, 'test', 0) }
+ assert_equal ['test', 'test.rb', 10] do
+ Kernel.eval('[\'test\', __FILE__, __LINE__]', nil, 'test.rb', 10)
+ end
+end
diff --git a/mrbgems/mruby-hash-ext/src/hash-ext.c b/mrbgems/mruby-hash-ext/src/hash-ext.c
index 937a7fddd..bce842cb4 100644
--- a/mrbgems/mruby-hash-ext/src/hash-ext.c
+++ b/mrbgems/mruby-hash-ext/src/hash-ext.c
@@ -23,7 +23,8 @@ static mrb_value
hash_values_at(mrb_state *mrb, mrb_value hash)
{
mrb_value *argv, result;
- int argc, i, ai;
+ mrb_int argc, i;
+ int ai;
mrb_get_args(mrb, "*", &argv, &argc);
result = mrb_ary_new_capa(mrb, argc);
diff --git a/mrbgems/mruby-object-ext/src/object.c b/mrbgems/mruby-object-ext/src/object.c
index 2bc9cbf4f..0dcc3cba7 100644
--- a/mrbgems/mruby-object-ext/src/object.c
+++ b/mrbgems/mruby-object-ext/src/object.c
@@ -63,7 +63,7 @@ static mrb_value
mrb_obj_instance_exec(mrb_state *mrb, mrb_value self)
{
mrb_value *argv;
- int argc;
+ mrb_int argc;
mrb_value blk;
struct RClass *c;
diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c
index bb5502b58..a82a674cf 100644
--- a/mrbgems/mruby-sprintf/src/sprintf.c
+++ b/mrbgems/mruby-sprintf/src/sprintf.c
@@ -471,7 +471,7 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv)
mrb_value
mrb_f_sprintf(mrb_state *mrb, mrb_value obj)
{
- int argc;
+ mrb_int argc;
mrb_value *argv;
mrb_get_args(mrb, "*", &argv, &argc);
diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c
index 3ec23c51f..2c0a406ad 100644
--- a/mrbgems/mruby-string-ext/src/string.c
+++ b/mrbgems/mruby-string-ext/src/string.c
@@ -113,7 +113,7 @@ static mrb_value
mrb_str_start_with(mrb_state *mrb, mrb_value self)
{
mrb_value *argv, sub;
- int argc, i;
+ mrb_int argc, i;
mrb_get_args(mrb, "*", &argv, &argc);
for (i = 0; i < argc; i++) {
@@ -142,7 +142,7 @@ static mrb_value
mrb_str_end_with(mrb_state *mrb, mrb_value self)
{
mrb_value *argv, sub;
- int argc, i;
+ mrb_int argc, i;
mrb_get_args(mrb, "*", &argv, &argc);
for (i = 0; i < argc; i++) {
diff --git a/mrbgems/mruby-string-utf8/src/string.c b/mrbgems/mruby-string-utf8/src/string.c
index 45dd66eec..886a6999f 100644
--- a/mrbgems/mruby-string-utf8/src/string.c
+++ b/mrbgems/mruby-string-utf8/src/string.c
@@ -356,7 +356,7 @@ static mrb_value
mrb_str_index_m(mrb_state *mrb, mrb_value str)
{
mrb_value *argv;
- int argc;
+ mrb_int argc;
mrb_value sub;
mrb_int pos;
@@ -440,7 +440,7 @@ static mrb_value
mrb_str_rindex_m(mrb_state *mrb, mrb_value str)
{
mrb_value *argv;
- int argc;
+ mrb_int argc;
mrb_value sub;
mrb_value vpos;
mrb_int pos, len = RSTRING_LEN(str);
diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c
index b5b498009..43cacbc4e 100644
--- a/mrbgems/mruby-struct/src/struct.c
+++ b/mrbgems/mruby-struct/src/struct.c
@@ -347,7 +347,7 @@ mrb_struct_s_def(mrb_state *mrb, mrb_value klass)
mrb_value b, st;
mrb_sym id;
mrb_value *argv;
- int argc;
+ mrb_int argc;
name = mrb_nil_value();
rest = mrb_nil_value();
@@ -428,7 +428,7 @@ static mrb_value
mrb_struct_initialize_m(mrb_state *mrb, /*int argc, mrb_value *argv,*/ mrb_value self)
{
mrb_value *argv;
- int argc;
+ mrb_int argc;
mrb_get_args(mrb, "*", &argv, &argc);
return mrb_struct_initialize_withArg(mrb, argc, argv, self);
diff --git a/mrblib/array.rb b/mrblib/array.rb
index 16e69d5d1..3218aa858 100644
--- a/mrblib/array.rb
+++ b/mrblib/array.rb
@@ -187,11 +187,8 @@ class Array
# internal method to convert multi-value to single value
def __svalue
- case self.size
- when 0
- return nil
- when 1
- self[0]
+ if self.size < 2
+ self.first
else
self
end
diff --git a/src/codegen.c b/src/codegen.c
index 015631a7a..2733e8a13 100644
--- a/src/codegen.c
+++ b/src/codegen.c
@@ -1448,7 +1448,7 @@ codegen(codegen_scope *s, node *tree, int val)
codegen(s, tree->cdr, val);
if (val) {
pop(); pop();
- genop(s, MKOP_ABC(OP_RANGE, cursp(), cursp(), 0));
+ genop(s, MKOP_ABC(OP_RANGE, cursp(), cursp(), FALSE));
push();
}
break;
@@ -1458,7 +1458,7 @@ codegen(codegen_scope *s, node *tree, int val)
codegen(s, tree->cdr, val);
if (val) {
pop(); pop();
- genop(s, MKOP_ABC(OP_RANGE, cursp(), cursp(), 1));
+ genop(s, MKOP_ABC(OP_RANGE, cursp(), cursp(), TRUE));
push();
}
break;
diff --git a/src/error.c b/src/error.c
index feaa61122..8f13dcf77 100644
--- a/src/error.c
+++ b/src/error.c
@@ -199,7 +199,7 @@ exc_debug_info(mrb_state *mrb, struct RObject *exc)
mrb_callinfo *ci = mrb->c->ci;
mrb_code *pc = ci->pc;
- mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "ciidx"), mrb_fixnum_value(ci - mrb->c->cibase));
+ mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "ciidx"), mrb_fixnum_value((mrb_int)(ci - mrb->c->cibase)));
while (ci >= mrb->c->cibase) {
mrb_code *err = ci->err;
@@ -207,8 +207,8 @@ exc_debug_info(mrb_state *mrb, struct RObject *exc)
if (err && ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) {
mrb_irep *irep = ci->proc->body.irep;
- int32_t const line = mrb_debug_get_line(irep, err - irep->iseq);
- char const* file = mrb_debug_get_filename(irep, err - irep->iseq);
+ int32_t const line = mrb_debug_get_line(irep, (uint32_t)(err - irep->iseq));
+ char const* file = mrb_debug_get_filename(irep, (uint32_t)(err - irep->iseq));
if (line != -1 && file) {
mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "file"), mrb_str_new_cstr(mrb, file));
mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "line"), mrb_fixnum_value(line));
diff --git a/src/parse.y b/src/parse.y
index 43c0c7321..0d281feeb 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -5263,8 +5263,8 @@ static void
parser_init_cxt(parser_state *p, mrbc_context *cxt)
{
if (!cxt) return;
- if (cxt->lineno) p->lineno = cxt->lineno;
if (cxt->filename) mrb_parser_set_filename(p, cxt->filename);
+ if (cxt->lineno) p->lineno = cxt->lineno;
if (cxt->syms) {
int i;
diff --git a/src/range.c b/src/range.c
index 6b1f7faa2..b59b234ef 100644
--- a/src/range.c
+++ b/src/range.c
@@ -33,7 +33,7 @@ range_check(mrb_state *mrb, mrb_value a, mrb_value b)
}
mrb_value
-mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, int excl)
+mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, mrb_bool excl)
{
struct RRange *r;
@@ -95,7 +95,7 @@ mrb_range_excl(mrb_state *mrb, mrb_value range)
}
static void
-range_init(mrb_state *mrb, mrb_value range, mrb_value beg, mrb_value end, int exclude_end)
+range_init(mrb_state *mrb, mrb_value range, mrb_value beg, mrb_value end, mrb_bool exclude_end)
{
struct RRange *r = mrb_range_ptr(range);
diff --git a/src/vm.c b/src/vm.c
index 9d62ce548..717c927c8 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -1114,7 +1114,7 @@ RETRY_TRY_BLOCK:
}
regs = mrb->c->stack;
regs[0] = m->env->stack[0];
- pc = m->body.irep->iseq;
+ pc = irep->iseq;
JUMP;
}
}