From f1d85c2f97904a17c0454d778ce6b59ea93bbd14 Mon Sep 17 00:00:00 2001 From: ksss Date: Thu, 24 Apr 2014 13:18:57 +0000 Subject: mrb_range_new excl flag use mrb_bool insteard of int --- include/mruby/range.h | 4 ++-- src/codegen.c | 4 ++-- src/range.c | 2 +- 3 files changed, 5 insertions(+), 5 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/src/codegen.c b/src/codegen.c index a36d609c6..f657c3a32 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/range.c b/src/range.c index 6b1f7faa2..95ef0f209 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; -- cgit v1.2.3 From aca3a1f3fb9c90f0414aa1d909a62bf25db0bfe8 Mon Sep 17 00:00:00 2001 From: ksss Date: Thu, 24 Apr 2014 13:25:59 +0000 Subject: range_init argument for exclude_end use mrb_bool --- src/range.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/range.c b/src/range.c index 95ef0f209..b59b234ef 100644 --- a/src/range.c +++ b/src/range.c @@ -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); -- cgit v1.2.3 From d6414fe112859192f953ce9e5f185971839fb495 Mon Sep 17 00:00:00 2001 From: Jun Hiroe Date: Fri, 25 Apr 2014 18:57:01 +0900 Subject: Add Array#keep_if --- mrbgems/mruby-array-ext/mrblib/array.rb | 30 ++++++++++++++++++++++++++++++ mrbgems/mruby-array-ext/test/array.rb | 14 ++++++++++++++ 2 files changed, 44 insertions(+) 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 -- cgit v1.2.3 From d2e4937ceaba5fa868392f8ede4020300e608c74 Mon Sep 17 00:00:00 2001 From: mirichi Date: Fri, 25 Apr 2014 21:36:52 +0900 Subject: Refactoring Array#__svalue --- mrblib/array.rb | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) 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 -- cgit v1.2.3 From fa1a1e6db8cd0307ac6e351625cfad0233d5f87f Mon Sep 17 00:00:00 2001 From: mirichi Date: Fri, 25 Apr 2014 21:49:29 +0900 Subject: Refactoring OP_CALL --- src/vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; } } -- cgit v1.2.3 From 215f8fdd645405aacc789ba42d38cb74a8605505 Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Fri, 25 Apr 2014 21:56:02 +0900 Subject: Fix lineno overwrite in parser_init_cxt. By reordering parsing string with mrb_parser_parse won't always start with line 1. --- src/parse.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; -- cgit v1.2.3 From d2011ce01a896cdc36ce5c8ac97de8845987cc96 Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Fri, 25 Apr 2014 21:59:52 +0900 Subject: Support file name and line argument in Kernel.eval . Only a nil binding will be supported. --- mrbgems/mruby-eval/src/eval.c | 63 ++++++++++++++++++++++++++++++++++++++--- mrbgems/mruby-eval/test/eval.rb | 7 +++++ 2 files changed, 66 insertions(+), 4 deletions(-) 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 -- cgit v1.2.3 From b5028421b9fc0df9c4706ee5e3095a9c00f8f383 Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Fri, 25 Apr 2014 22:02:10 +0900 Subject: Use mrb_int in mrbgem rest argument getting. --- mrbgems/mruby-hash-ext/src/hash-ext.c | 3 ++- mrbgems/mruby-object-ext/src/object.c | 2 +- mrbgems/mruby-sprintf/src/sprintf.c | 2 +- mrbgems/mruby-string-ext/src/string.c | 4 ++-- mrbgems/mruby-string-utf8/src/string.c | 4 ++-- mrbgems/mruby-struct/src/struct.c | 4 ++-- 6 files changed, 10 insertions(+), 9 deletions(-) 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); -- cgit v1.2.3 From 1fdc072032c7d4ee68338d1addcb8ef0c2cba9f2 Mon Sep 17 00:00:00 2001 From: kyab Date: Sat, 26 Apr 2014 00:00:40 +0900 Subject: Fix MSVC warnings for error.c --- src/error.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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)); -- cgit v1.2.3