Commit 2202e412 authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto

Merge branch 'master' of github.com:mruby/mruby

parents 44ec41a7 b8e5cb71
...@@ -19,13 +19,13 @@ typedef struct mrb_range_edges { ...@@ -19,13 +19,13 @@ typedef struct mrb_range_edges {
struct RRange { struct RRange {
MRB_OBJECT_HEADER; MRB_OBJECT_HEADER;
mrb_range_edges *edges; mrb_range_edges *edges;
int excl; mrb_bool excl : 1;
}; };
#define mrb_range_ptr(v) ((struct RRange*)(mrb_ptr(v))) #define mrb_range_ptr(v) ((struct RRange*)(mrb_ptr(v)))
#define mrb_range_value(p) mrb_obj_value((void*)(p)) #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); mrb_bool mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len);
#if defined(__cplusplus) #if defined(__cplusplus)
......
...@@ -627,4 +627,34 @@ class Array ...@@ -627,4 +627,34 @@ class Array
end end
self self
end 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 end
...@@ -252,3 +252,17 @@ assert("Array#delete_if") do ...@@ -252,3 +252,17 @@ assert("Array#delete_if") do
a = [ 1, 2, 3, 4, 5 ] a = [ 1, 2, 3, 4, 5 ]
assert_equal [1, 2, 3], a.delete_if { |val| val > 3 } assert_equal [1, 2, 3], a.delete_if { |val| val > 3 }
end 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
#include "mruby.h" #include "mruby.h"
#include "mruby/compile.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 static mrb_value
f_eval(mrb_state *mrb, mrb_value self) f_eval(mrb_state *mrb, mrb_value self)
{ {
char *s; 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 ret;
return mrb_load_nstring(mrb, s, len);
} }
void void
mrb_mruby_eval_gem_init(mrb_state* mrb) 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 void
......
...@@ -6,3 +6,10 @@ end ...@@ -6,3 +6,10 @@ end
assert('eval') do assert('eval') do
assert_equal(10) { eval '1 * 10' } assert_equal(10) { eval '1 * 10' }
end 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
...@@ -23,7 +23,8 @@ static mrb_value ...@@ -23,7 +23,8 @@ static mrb_value
hash_values_at(mrb_state *mrb, mrb_value hash) hash_values_at(mrb_state *mrb, mrb_value hash)
{ {
mrb_value *argv, result; mrb_value *argv, result;
int argc, i, ai; mrb_int argc, i;
int ai;
mrb_get_args(mrb, "*", &argv, &argc); mrb_get_args(mrb, "*", &argv, &argc);
result = mrb_ary_new_capa(mrb, argc); result = mrb_ary_new_capa(mrb, argc);
......
...@@ -63,7 +63,7 @@ static mrb_value ...@@ -63,7 +63,7 @@ static mrb_value
mrb_obj_instance_exec(mrb_state *mrb, mrb_value self) mrb_obj_instance_exec(mrb_state *mrb, mrb_value self)
{ {
mrb_value *argv; mrb_value *argv;
int argc; mrb_int argc;
mrb_value blk; mrb_value blk;
struct RClass *c; struct RClass *c;
......
...@@ -471,7 +471,7 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv) ...@@ -471,7 +471,7 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv)
mrb_value mrb_value
mrb_f_sprintf(mrb_state *mrb, mrb_value obj) mrb_f_sprintf(mrb_state *mrb, mrb_value obj)
{ {
int argc; mrb_int argc;
mrb_value *argv; mrb_value *argv;
mrb_get_args(mrb, "*", &argv, &argc); mrb_get_args(mrb, "*", &argv, &argc);
......
...@@ -113,7 +113,7 @@ static mrb_value ...@@ -113,7 +113,7 @@ static mrb_value
mrb_str_start_with(mrb_state *mrb, mrb_value self) mrb_str_start_with(mrb_state *mrb, mrb_value self)
{ {
mrb_value *argv, sub; mrb_value *argv, sub;
int argc, i; mrb_int argc, i;
mrb_get_args(mrb, "*", &argv, &argc); mrb_get_args(mrb, "*", &argv, &argc);
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
...@@ -142,7 +142,7 @@ static mrb_value ...@@ -142,7 +142,7 @@ static mrb_value
mrb_str_end_with(mrb_state *mrb, mrb_value self) mrb_str_end_with(mrb_state *mrb, mrb_value self)
{ {
mrb_value *argv, sub; mrb_value *argv, sub;
int argc, i; mrb_int argc, i;
mrb_get_args(mrb, "*", &argv, &argc); mrb_get_args(mrb, "*", &argv, &argc);
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
......
...@@ -356,7 +356,7 @@ static mrb_value ...@@ -356,7 +356,7 @@ static mrb_value
mrb_str_index_m(mrb_state *mrb, mrb_value str) mrb_str_index_m(mrb_state *mrb, mrb_value str)
{ {
mrb_value *argv; mrb_value *argv;
int argc; mrb_int argc;
mrb_value sub; mrb_value sub;
mrb_int pos; mrb_int pos;
...@@ -440,7 +440,7 @@ static mrb_value ...@@ -440,7 +440,7 @@ static mrb_value
mrb_str_rindex_m(mrb_state *mrb, mrb_value str) mrb_str_rindex_m(mrb_state *mrb, mrb_value str)
{ {
mrb_value *argv; mrb_value *argv;
int argc; mrb_int argc;
mrb_value sub; mrb_value sub;
mrb_value vpos; mrb_value vpos;
mrb_int pos, len = RSTRING_LEN(str); mrb_int pos, len = RSTRING_LEN(str);
......
...@@ -347,7 +347,7 @@ mrb_struct_s_def(mrb_state *mrb, mrb_value klass) ...@@ -347,7 +347,7 @@ mrb_struct_s_def(mrb_state *mrb, mrb_value klass)
mrb_value b, st; mrb_value b, st;
mrb_sym id; mrb_sym id;
mrb_value *argv; mrb_value *argv;
int argc; mrb_int argc;
name = mrb_nil_value(); name = mrb_nil_value();
rest = mrb_nil_value(); rest = mrb_nil_value();
...@@ -428,7 +428,7 @@ static mrb_value ...@@ -428,7 +428,7 @@ static mrb_value
mrb_struct_initialize_m(mrb_state *mrb, /*int argc, mrb_value *argv,*/ mrb_value self) mrb_struct_initialize_m(mrb_state *mrb, /*int argc, mrb_value *argv,*/ mrb_value self)
{ {
mrb_value *argv; mrb_value *argv;
int argc; mrb_int argc;
mrb_get_args(mrb, "*", &argv, &argc); mrb_get_args(mrb, "*", &argv, &argc);
return mrb_struct_initialize_withArg(mrb, argc, argv, self); return mrb_struct_initialize_withArg(mrb, argc, argv, self);
......
...@@ -187,11 +187,8 @@ class Array ...@@ -187,11 +187,8 @@ class Array
# internal method to convert multi-value to single value # internal method to convert multi-value to single value
def __svalue def __svalue
case self.size if self.size < 2
when 0 self.first
return nil
when 1
self[0]
else else
self self
end end
......
...@@ -1448,7 +1448,7 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -1448,7 +1448,7 @@ codegen(codegen_scope *s, node *tree, int val)
codegen(s, tree->cdr, val); codegen(s, tree->cdr, val);
if (val) { if (val) {
pop(); pop(); pop(); pop();
genop(s, MKOP_ABC(OP_RANGE, cursp(), cursp(), 0)); genop(s, MKOP_ABC(OP_RANGE, cursp(), cursp(), FALSE));
push(); push();
} }
break; break;
...@@ -1458,7 +1458,7 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -1458,7 +1458,7 @@ codegen(codegen_scope *s, node *tree, int val)
codegen(s, tree->cdr, val); codegen(s, tree->cdr, val);
if (val) { if (val) {
pop(); pop(); pop(); pop();
genop(s, MKOP_ABC(OP_RANGE, cursp(), cursp(), 1)); genop(s, MKOP_ABC(OP_RANGE, cursp(), cursp(), TRUE));
push(); push();
} }
break; break;
......
...@@ -199,7 +199,7 @@ exc_debug_info(mrb_state *mrb, struct RObject *exc) ...@@ -199,7 +199,7 @@ exc_debug_info(mrb_state *mrb, struct RObject *exc)
mrb_callinfo *ci = mrb->c->ci; mrb_callinfo *ci = mrb->c->ci;
mrb_code *pc = ci->pc; 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) { while (ci >= mrb->c->cibase) {
mrb_code *err = ci->err; mrb_code *err = ci->err;
...@@ -207,8 +207,8 @@ exc_debug_info(mrb_state *mrb, struct RObject *exc) ...@@ -207,8 +207,8 @@ exc_debug_info(mrb_state *mrb, struct RObject *exc)
if (err && ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) { if (err && ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) {
mrb_irep *irep = ci->proc->body.irep; mrb_irep *irep = ci->proc->body.irep;
int32_t const line = mrb_debug_get_line(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, err - irep->iseq); char const* file = mrb_debug_get_filename(irep, (uint32_t)(err - irep->iseq));
if (line != -1 && file) { 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, "file"), mrb_str_new_cstr(mrb, file));
mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "line"), mrb_fixnum_value(line)); mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "line"), mrb_fixnum_value(line));
......
...@@ -5263,8 +5263,8 @@ static void ...@@ -5263,8 +5263,8 @@ static void
parser_init_cxt(parser_state *p, mrbc_context *cxt) parser_init_cxt(parser_state *p, mrbc_context *cxt)
{ {
if (!cxt) return; if (!cxt) return;
if (cxt->lineno) p->lineno = cxt->lineno;
if (cxt->filename) mrb_parser_set_filename(p, cxt->filename); if (cxt->filename) mrb_parser_set_filename(p, cxt->filename);
if (cxt->lineno) p->lineno = cxt->lineno;
if (cxt->syms) { if (cxt->syms) {
int i; int i;
......
...@@ -33,7 +33,7 @@ range_check(mrb_state *mrb, mrb_value a, mrb_value b) ...@@ -33,7 +33,7 @@ range_check(mrb_state *mrb, mrb_value a, mrb_value b)
} }
mrb_value 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; struct RRange *r;
...@@ -95,7 +95,7 @@ mrb_range_excl(mrb_state *mrb, mrb_value range) ...@@ -95,7 +95,7 @@ mrb_range_excl(mrb_state *mrb, mrb_value range)
} }
static void 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); struct RRange *r = mrb_range_ptr(range);
......
...@@ -1114,7 +1114,7 @@ RETRY_TRY_BLOCK: ...@@ -1114,7 +1114,7 @@ RETRY_TRY_BLOCK:
} }
regs = mrb->c->stack; regs = mrb->c->stack;
regs[0] = m->env->stack[0]; regs[0] = m->env->stack[0];
pc = m->body.irep->iseq; pc = irep->iseq;
JUMP; JUMP;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment