diff options
28 files changed, 301 insertions, 171 deletions
@@ -18,9 +18,9 @@ of the Ministry of Economy, Trade and Industry of Japan. ## How to get mruby -The stable version 1.0.0 of mruby can be downloaded via the following URL: +The stable version 1.1.0 of mruby can be downloaded via the following URL: - https://github.com/mruby/mruby/archive/1.0.0.zip + https://github.com/mruby/mruby/archive/1.1.0.zip The latest development version of mruby can be downloaded via the following URL: @@ -52,7 +52,11 @@ MRuby.each_target do |target| gems.map do |gem| current_dir = gem.dir.relative_path_from(Dir.pwd) relative_from_root = gem.dir.relative_path_from(MRUBY_ROOT) - current_build_dir = "#{build_dir}/#{relative_from_root}" + current_build_dir = File.expand_path "#{build_dir}/#{relative_from_root}" + + if current_build_dir !~ /^#{build_dir}/ + current_build_dir = "#{build_dir}/mrbgems/#{gem.name}" + end gem.bins.each do |bin| exec = exefile("#{build_dir}/bin/#{bin}") diff --git a/include/mruby.h b/include/mruby.h index 68b0c5b79..c07bca462 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -439,6 +439,9 @@ MRB_API void* mrb_alloca(mrb_state *mrb, size_t); MRB_API void mrb_state_atexit(mrb_state *mrb, mrb_atexit_func func); +MRB_API void mrb_show_version(mrb_state *mrb); +MRB_API void mrb_show_copyright(mrb_state *mrb); + #ifdef MRB_DEBUG #include <assert.h> #define mrb_assert(p) assert(p) diff --git a/include/mruby/khash.h b/include/mruby/khash.h index 8a62e3ee6..6a4861bda 100644 --- a/include/mruby/khash.h +++ b/include/mruby/khash.h @@ -148,20 +148,23 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len) new_n_buckets = KHASH_MIN_SIZE; \ khash_power2(new_n_buckets); \ { \ + kh_##name##_t hh; \ uint8_t *old_ed_flags = h->ed_flags; \ khkey_t *old_keys = h->keys; \ khval_t *old_vals = h->vals; \ khint_t old_n_buckets = h->n_buckets; \ khint_t i; \ - h->n_buckets = new_n_buckets; \ - kh_alloc_##name(mrb, h); \ + hh.n_buckets = new_n_buckets; \ + kh_alloc_##name(mrb, &hh); \ /* relocate */ \ for (i=0 ; i<old_n_buckets ; i++) { \ if (!__ac_iseither(old_ed_flags, i)) { \ - khint_t k = kh_put_##name(mrb, h, old_keys[i], NULL); \ - if (kh_is_map) kh_value(h,k) = old_vals[i]; \ + khint_t k = kh_put_##name(mrb, &hh, old_keys[i], NULL); \ + if (kh_is_map) kh_value(&hh,k) = old_vals[i]; \ } \ } \ + /* copy hh to h */ \ + *h = hh; \ mrb_free(mrb, old_keys); \ } \ } \ @@ -237,7 +237,8 @@ module MiniRake # Time stamp for file task. def timestamp - File::stat(name.to_s).mtime + stat = File::stat(name.to_s) + stat.directory? ? Time.at(0) : stat.mtime end end @@ -254,12 +255,14 @@ module MiniRake # Declare a set of files tasks to create the given directories on # demand. - def directory(dir) - path = [] - Sys.split_all(dir).each do |p| - path << p - FileTask.define_task(File.join(path)) do |t| - Sys.makedirs(t.name) + def directory(args, &block) + MiniRake::FileTask.define_task(args) do |t| + block.call(t) unless block.nil? + dir = args.is_a?(Hash) ? args.keys.first : args + (dir.split(File::SEPARATOR) + ['']).inject do |acc, part| + (acc + File::SEPARATOR).tap do |d| + Dir.mkdir(d) unless File.exists? d + end + part end end end diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c b/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c index f1bf34a06..610a5db6f 100755 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c @@ -203,9 +203,6 @@ mrb_debug_set_break_line( mrb_state *mrb, mrb_debug_context *dbg, const char *fi } set_file = mrb_malloc(mrb, strlen(file) + 1); - if(set_file == NULL) { - return MRB_DEBUG_NOBUF; - } index = dbg->bpnum; dbg->bp[index].bpno = dbg->next_bpno; @@ -243,10 +240,6 @@ mrb_debug_set_break_method( mrb_state *mrb, mrb_debug_context *dbg, const char * if(class_name != NULL) { set_class = mrb_malloc(mrb, strlen(class_name) + 1); - if(set_class == NULL) { - return MRB_DEBUG_NOBUF; - } - strncpy(set_class, class_name, strlen(class_name) + 1); } else { @@ -254,12 +247,6 @@ mrb_debug_set_break_method( mrb_state *mrb, mrb_debug_context *dbg, const char * } set_method = mrb_malloc(mrb, strlen(method_name) + 1); - if(set_method == NULL) { - if(set_class != NULL) { - mrb_free(mrb, (void*)set_class); - } - return MRB_DEBUG_NOBUF; - } strncpy(set_method, method_name, strlen(method_name) + 1); diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c b/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c index 734f03f0a..03846cd50 100755 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c @@ -45,18 +45,18 @@ build_path(mrb_state *mrb, const char *dir, const char *base) len = strlen(base) + 1; if (strcmp(dir, ".")) { - len += strlen(dir) + strlen("/"); + len += strlen(dir) + sizeof("/") - 1; } - if ((path = mrb_malloc(mrb, len)) != NULL) { - memset(path, 0, len); + path = mrb_malloc(mrb, len); + memset(path, 0, len); - if (strcmp(dir, ".")) { - strcat(path, dir); - strcat(path, "/"); - } - strcat(path, base); + if (strcmp(dir, ".")) { + strcat(path, dir); + strcat(path, "/"); } + strcat(path, base); + return path; } @@ -73,10 +73,10 @@ dirname(mrb_state *mrb, const char *path) p = strrchr(path, '/'); len = p != NULL ? p - path : strlen(path); - if ((dir = mrb_malloc(mrb, len + 1)) != NULL) { - strncpy(dir, path, len); - dir[len] = '\0'; - } + dir = mrb_malloc(mrb, len + 1); + strncpy(dir, path, len); + dir[len] = '\0'; + return dir; } @@ -85,9 +85,7 @@ source_file_new(mrb_state *mrb, mrb_debug_context *dbg, char *filename) { source_file *file = NULL; - if ((file = mrb_malloc(mrb, sizeof(source_file))) == NULL) { - return NULL; - } + file = mrb_malloc(mrb, sizeof(source_file)); memset(file, '\0', sizeof(source_file)); file->fp = fopen(filename, "rb"); diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c b/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c index 9759badfe..d4ec3d5f8 100755 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c @@ -256,7 +256,7 @@ parse_breakcommand(mrdb_state *mrdb, const char **file, uint32_t *line, char **c } args = mrdb->words[1]; - if((body = strchr(args, ':')) == NULL) { + if((body = strrchr(args, ':')) == NULL) { body = args; type = check_bptype(body); } else { diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c b/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c index 6520af46e..b40915909 100755 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c @@ -255,11 +255,11 @@ replace_ext(mrb_state *mrb, const char *filename, const char *ext) len = strlen(filename); } - if ((s = mrb_malloc(mrb, len + strlen(ext) + 1)) != NULL) { - memset(s, '\0', len + strlen(ext) + 1); - strncpy(s, filename, len); - strcat(s, ext); - } + s = mrb_malloc(mrb, len + strlen(ext) + 1); + memset(s, '\0', len + strlen(ext) + 1); + strncpy(s, filename, len); + strcat(s, ext); + return s; } diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c b/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c index ca120dc51..da235fad8 100755 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c @@ -19,8 +19,6 @@ #include "apibreak.h" #include "apilist.h" -void mrb_show_version(mrb_state *); -void mrb_show_copyright(mrb_state *); void mrdb_state_free(mrb_state *); static mrb_debug_context *_debug_context = NULL; @@ -275,7 +273,7 @@ get_command(mrb_state *mrb, mrdb_state *mrdb) if (i == 0 && feof(stdin)) { clearerr(stdin); strcpy(mrdb->command, "quit"); - i += strlen("quit"); + i += sizeof("quit") - 1; } if (i == MAX_COMMAND_LINE) { @@ -572,7 +570,7 @@ mrb_code_fetch_hook(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value *reg switch (dbg->xm) { case DBG_STEP: case DBG_NEXT: // temporary - if (dbg->prvfile == file && dbg->prvline == line) { + if (!file || (dbg->prvfile == file && dbg->prvline == line)) { return; } dbg->method_bpno = 0; @@ -652,13 +650,13 @@ main(int argc, char **argv) mrb_debug_context* dbg_backup; debug_command *cmd; + l_restart: + if (mrb == NULL) { fputs("Invalid mrb_state, exiting mruby\n", stderr); return EXIT_FAILURE; } - l_restart: - /* parse command parameters */ n = parse_args(mrb, argc, argv, &args); if (n == EXIT_FAILURE || args.rfp == NULL) { diff --git a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c index 905bd2049..0f3649a35 100644 --- a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +++ b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c @@ -193,9 +193,6 @@ is_code_block_open(struct mrb_parser_state *parser) return code_block_open; } -void mrb_show_version(mrb_state *); -void mrb_show_copyright(mrb_state *); - struct _args { mrb_bool verbose : 1; int argc; diff --git a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c index 247323b4e..442133f92 100644 --- a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +++ b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c @@ -24,9 +24,6 @@ p(mrb_state *mrb, mrb_value obj) #define p(mrb,obj) mrb_p(mrb,obj) #endif -void mrb_show_version(mrb_state *); -void mrb_show_copyright(mrb_state *); - struct _args { FILE *rfp; char* cmdline; diff --git a/mrbgems/mruby-enum-ext/mrblib/enum.rb b/mrbgems/mruby-enum-ext/mrblib/enum.rb index b13d00a84..f6629ed79 100644 --- a/mrbgems/mruby-enum-ext/mrblib/enum.rb +++ b/mrbgems/mruby-enum-ext/mrblib/enum.rb @@ -37,7 +37,7 @@ module Enumerable # a.drop_while {|i| i < 3 } #=> [3, 4, 5, 0] def drop_while(&block) - return to_enum :drop_while unless block_given? + return to_enum :drop_while unless block ary, state = [], false self.each do |*val| @@ -83,7 +83,7 @@ module Enumerable # a.take_while {|i| i < 3 } #=> [1, 2] def take_while(&block) - return to_enum :take_while unless block_given? + return to_enum :take_while unless block ary = [] self.each do |*val| @@ -167,7 +167,7 @@ module Enumerable # (1..6).group_by {|i| i%3} #=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]} def group_by(&block) - return to_enum :group_by unless block_given? + return to_enum :group_by unless block h = {} self.each do |*val| @@ -189,7 +189,7 @@ module Enumerable # If no block is given, an enumerator is returned instead. def sort_by(&block) - return to_enum :sort_by unless block_given? + return to_enum :sort_by unless block ary = [] orig = [] @@ -275,7 +275,7 @@ module Enumerable # [1, 2, 3, 4].flat_map { |e| [e, -e] } #=> [1, -1, 2, -2, 3, -3, 4, -4] # [[1, 2], [3, 4]].flat_map { |e| e + [100] } #=> [1, 2, 100, 3, 4, 100] def flat_map(&block) - return to_enum :flat_map unless block_given? + return to_enum :flat_map unless block ary = [] self.each do |*e| @@ -303,7 +303,7 @@ module Enumerable # %w[albatross dog horse].max_by {|x| x.length } #=> "albatross" def max_by(&block) - return to_enum :max_by unless block_given? + return to_enum :max_by unless block first = true max = nil @@ -337,7 +337,7 @@ module Enumerable # %w[albatross dog horse].min_by {|x| x.length } #=> "dog" def min_by(&block) - return to_enum :min_by unless block_given? + return to_enum :min_by unless block first = true min = nil @@ -411,7 +411,7 @@ module Enumerable # %w(albatross dog horse).minmax_by { |x| x.length } #=> ["dog", "albatross"] def minmax_by(&block) - return to_enum :minmax_by unless block_given? + return to_enum :minmax_by unless block max = nil max_cmp = nil @@ -517,7 +517,7 @@ module Enumerable def each_with_object(obj=nil, &block) raise ArgumentError, "wrong number of arguments (0 for 1)" if obj == nil - return to_enum(:each_with_object, obj) unless block_given? + return to_enum(:each_with_object, obj) unless block self.each {|*val| block.call(val.__svalue, obj) } obj @@ -542,7 +542,7 @@ module Enumerable # def reverse_each(&block) - return to_enum :reverse_each unless block_given? + return to_enum :reverse_each unless block ary = self.to_a i = ary.size - 1 @@ -574,7 +574,7 @@ module Enumerable # def cycle(n=nil, &block) - return to_enum(:cycle, n) if !block_given? && n == nil + return to_enum(:cycle, n) if !block && n == nil ary = [] if n == nil @@ -623,7 +623,7 @@ module Enumerable # def find_index(val=NONE, &block) - return to_enum(:find_index, val) if !block_given? && val == NONE + return to_enum(:find_index, val) if !block && val == NONE idx = 0 if block diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index bad084dd6..8bfa2f112 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -56,16 +56,11 @@ search_variable(mrb_state *mrb, mrb_sym vsym, int bnest) } static mrb_bool -potential_upvar_p(struct mrb_locals *lv, uint16_t v, uint16_t nlocals) +potential_upvar_p(struct mrb_locals *lv, uint16_t v, int argc, uint16_t nlocals) { - int i; - if (v >= nlocals) return FALSE; /* skip arguments */ - for (i=0; i<nlocals-1; i++) { - if (lv[i].name == 0) - return i < v; - } + if (v < argc+1) return FALSE; return TRUE; } @@ -74,10 +69,19 @@ patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest) { size_t i; mrb_code c; + int argc = 0; for (i = 0; i < irep->ilen; i++) { c = irep->iseq[i]; switch(GET_OPCODE(c)){ + case OP_ENTER: + { + mrb_aspec ax = GETARG_Ax(c); + /* extra 1 means a slot for block */ + argc = MRB_ASPEC_REQ(ax)+MRB_ASPEC_OPT(ax)+MRB_ASPEC_REST(ax)+MRB_ASPEC_POST(ax)+1; + } + break; + case OP_EPUSH: patch_irep(mrb, irep->reps[GETARG_Bx(c)], bnest + 1); break; @@ -106,7 +110,7 @@ patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest) case OP_MOVE: /* src part */ - if (potential_upvar_p(irep->lv, GETARG_B(c), irep->nlocals)) { + if (potential_upvar_p(irep->lv, GETARG_B(c), argc, irep->nlocals)) { mrb_code arg = search_variable(mrb, irep->lv[GETARG_B(c) - 1].name, bnest); if (arg != 0) { /* must replace */ @@ -114,7 +118,7 @@ patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest) } } /* dst part */ - if (potential_upvar_p(irep->lv, GETARG_A(c), irep->nlocals)) { + if (potential_upvar_p(irep->lv, GETARG_A(c), argc, irep->nlocals)) { mrb_code arg = search_variable(mrb, irep->lv[GETARG_A(c) - 1].name, bnest); if (arg != 0) { /* must replace */ diff --git a/mrbgems/mruby-string-ext/mrblib/string.rb b/mrbgems/mruby-string-ext/mrblib/string.rb index 88bdd9090..2b61fdb48 100644 --- a/mrbgems/mruby-string-ext/mrblib/string.rb +++ b/mrbgems/mruby-string-ext/mrblib/string.rb @@ -244,4 +244,70 @@ class String return str + self if pos == 0 return self[0..pos - 1] + str + self[pos..-1] end + + ## + # call-seq: + # str.ljust(integer, padstr=' ') -> new_str + # + # If <i>integer</i> is greater than the length of <i>str</i>, returns a new + # <code>String</code> of length <i>integer</i> with <i>str</i> left justified + # and padded with <i>padstr</i>; otherwise, returns <i>str</i>. + # + # "hello".ljust(4) #=> "hello" + # "hello".ljust(20) #=> "hello " + # "hello".ljust(20, '1234') #=> "hello123412341234123" + def ljust(idx, padstr = ' ') + if idx <= self.size + return self + end + newstr = self.dup + newstr << padstr + while newstr.size <= idx + newstr << padstr + end + return newstr.slice(0,idx) + end + + # str.upto(other_str, exclusive=false) {|s| block } -> str + # str.upto(other_str, exclusive=false) -> an_enumerator + # + # Iterates through successive values, starting at <i>str</i> and + # ending at <i>other_str</i> inclusive, passing each value in turn to + # the block. The <code>String#succ</code> method is used to generate + # each value. If optional second argument exclusive is omitted or is false, + # the last value will be included; otherwise it will be excluded. + # + # If no block is given, an enumerator is returned instead. + # + # "a8".upto("b6") {|s| print s, ' ' } + # for s in "a8".."b6" + # print s, ' ' + # end + # + # <em>produces:</em> + # + # a8 a9 b0 b1 b2 b3 b4 b5 b6 + # a8 a9 b0 b1 b2 b3 b4 b5 b6 + # + # If <i>str</i> and <i>other_str</i> contains only ascii numeric characters, + # both are recognized as decimal numbers. In addition, the width of + # string (e.g. leading zeros) is handled appropriately. + # + # "9".upto("11").to_a #=> ["9", "10", "11"] + # "25".upto("5").to_a #=> [] + # "07".upto("11").to_a #=> ["07", "08", "09", "10", "11"] + # + def upto(other_str, excl=false, &block) + return to_enum :upto, other_str, excl unless block + + str = self + n = self.<=>other_str + return self if n > 0 || (self == other_str && excl) + while true + block.call(str) + return self if !excl && str == other_str + str = str.succ + return self if excl && str == other_str + end + end end diff --git a/mrbgems/mruby-string-ext/test/string.rb b/mrbgems/mruby-string-ext/test/string.rb index 9fa835249..14e00428e 100644 --- a/mrbgems/mruby-string-ext/test/string.rb +++ b/mrbgems/mruby-string-ext/test/string.rb @@ -386,3 +386,72 @@ assert('String#prepend') do assert_equal "hello world", a.prepend("hello ") assert_equal "hello world", a end + +assert('String#ljust') do + assert_equal "hello", "hello".ljust(4) + assert_equal "hello ", "hello".ljust(20) + assert_equal "hello123412341234123", "hello".ljust(20, '1234') + assert_equal "hello", "hello".ljust(-3) +end + +assert('String#upto') do + a = "aa" + start = "aa" + count = 0 + assert_equal("aa", a.upto("zz") {|s| + assert_equal(start, s) + start.succ! + count += 1 + }) + assert_equal(676, count) + + a = "a" + start = "a" + count = 0 + assert_equal("a", a.upto("a") {|s| + assert_equal(start, s) + start.succ! + count += 1 + }) + assert_equal(1, count) + + a = "a" + start = "a" + count = 0 + assert_equal("a", a.upto("b", true) {|s| + assert_equal(start, s) + start.succ! + count += 1 + }) + assert_equal(1, count) + + a = "0" + start = "0" + count = 0 + assert_equal("0", a.upto("0") {|s| + assert_equal(start, s) + start.succ! + count += 1 + }) + assert_equal(1, count) + + a = "0" + start = "0" + count = 0 + assert_equal("0", a.upto("-1") {|s| + assert_equal(start, s) + start.succ! + count += 1 + }) + assert_equal(0, count) + + a = "-1" + start = "-1" + count = 0 + assert_equal("-1", a.upto("-2") {|s| + assert_equal(start, s) + start.succ! + count += 1 + }) + assert_equal(2, count) +end diff --git a/mrbgems/mruby-struct/mrblib/struct.rb b/mrbgems/mruby-struct/mrblib/struct.rb index 5d0ede90f..57f100acd 100644 --- a/mrbgems/mruby-struct/mrblib/struct.rb +++ b/mrbgems/mruby-struct/mrblib/struct.rb @@ -45,6 +45,37 @@ if Object.const_defined?(:Struct) } ary end + + def _inspect + str = "#<struct #{self.class.to_s} " + buf = [] + self.each_pair do |k,v| + buf.push [k.to_s + "=" + v._inspect] + end + str + buf.join(", ") + ">" + end + + ## + # call-seq: + # struct.to_s -> string + # struct.inspect -> string + # + # Describe the contents of this struct in a string. + # + # 15.2.18.4.10(x) + # + def inspect + begin + self._inspect + rescue SystemStackError + "#<struct #{self.class.to_s}:...>" + end + end + + ## + # 15.2.18.4.11(x) + # + alias to_s inspect end end diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c index 420052e4d..4d3c66f7b 100644 --- a/mrbgems/mruby-struct/src/struct.c +++ b/mrbgems/mruby-struct/src/struct.c @@ -412,68 +412,6 @@ mrb_struct_initialize_m(mrb_state *mrb, /*int argc, mrb_value *argv,*/ mrb_value return mrb_struct_initialize_withArg(mrb, argc, argv, self); } -static mrb_value -inspect_struct(mrb_state *mrb, mrb_value s, mrb_bool recur) -{ - const char *cn = mrb_class_name(mrb, mrb_obj_class(mrb, s)); - mrb_value members, str = mrb_str_new_lit(mrb, "#<struct "); - mrb_value *ptr; - const mrb_value *ptr_members; - mrb_int i, len; - - if (cn) { - mrb_str_append(mrb, str, mrb_str_new_cstr(mrb, cn)); - } - if (recur) { - return mrb_str_cat_lit(mrb, str, ":...>"); - } - - members = mrb_struct_members(mrb, s); - ptr_members = RARRAY_PTR(members); - ptr = RSTRUCT_PTR(s); - len = RSTRUCT_LEN(s); - for (i=0; i<len; i++) { - mrb_value slot; - mrb_sym id; - const char *name; - mrb_int namelen; - - if (i > 0) { - mrb_str_cat_lit(mrb, str, ", "); - } - else if (cn) { - mrb_str_cat_lit(mrb, str, " "); - } - slot = ptr_members[i]; - id = mrb_symbol(slot); - name = mrb_sym2name_len(mrb, id, &namelen); - if (is_local_id(mrb, name) || is_const_id(mrb, name)) { - mrb_str_append(mrb, str, mrb_str_new(mrb, name, namelen)); - } - else { - mrb_str_append(mrb, str, mrb_inspect(mrb, slot)); - } - mrb_str_cat_lit(mrb, str, "="); - mrb_str_append(mrb, str, mrb_inspect(mrb, ptr[i])); - } - mrb_str_cat_lit(mrb, str, ">"); - - return str; -} - -/* - * call-seq: - * struct.to_s -> string - * struct.inspect -> string - * - * Describe the contents of this struct in a string. - */ -static mrb_value -mrb_struct_inspect(mrb_state *mrb, mrb_value s) -{ - return inspect_struct(mrb, s, FALSE); -} - /* 15.2.18.4.9 */ /* :nodoc: */ static mrb_value @@ -845,8 +783,6 @@ mrb_mruby_struct_gem_init(mrb_state* mrb) mrb_define_method(mrb, st, "members", mrb_struct_members_m, MRB_ARGS_NONE()); /* 15.2.18.4.6 */ mrb_define_method(mrb, st, "initialize", mrb_struct_initialize_m,MRB_ARGS_ANY()); /* 15.2.18.4.8 */ mrb_define_method(mrb, st, "initialize_copy", mrb_struct_init_copy, MRB_ARGS_REQ(1)); /* 15.2.18.4.9 */ - mrb_define_method(mrb, st, "inspect", mrb_struct_inspect, MRB_ARGS_NONE()); /* 15.2.18.4.10(x) */ - mrb_define_alias(mrb, st, "to_s", "inspect"); /* 15.2.18.4.11(x) */ mrb_define_method(mrb, st, "eql?", mrb_struct_eql, MRB_ARGS_REQ(1)); /* 15.2.18.4.12(x) */ mrb_define_method(mrb, st, "size", mrb_struct_len, MRB_ARGS_NONE()); diff --git a/mrblib/enum.rb b/mrblib/enum.rb index 41fd97fe7..6bf219283 100644 --- a/mrblib/enum.rb +++ b/mrblib/enum.rb @@ -72,7 +72,7 @@ module Enumerable # # ISO 15.3.2.2.3 def collect(&block) - return to_enum :collect unless block_given? + return to_enum :collect unless block ary = [] self.each{|*val| @@ -108,7 +108,7 @@ module Enumerable # # ISO 15.3.2.2.5 def each_with_index(&block) - return to_enum :each_with_index unless block_given? + return to_enum :each_with_index unless block i = 0 self.each{|*val| @@ -146,7 +146,7 @@ module Enumerable # # ISO 15.3.2.2.8 def find_all(&block) - return to_enum :find_all unless block_given? + return to_enum :find_all unless block ary = [] self.each{|*val| diff --git a/mrblib/string.rb b/mrblib/string.rb index 322cd0788..66a668e11 100644 --- a/mrblib/string.rb +++ b/mrblib/string.rb @@ -146,7 +146,16 @@ class String ## # ISO 15.2.10.5.27 def match(re, &block) - re.match(self, &block) + if re.respond_to? :to_str + if Object.const_defined?(:Regexp) + r = Regexp.new(re) + r.match(self, &block) + else + raise NotImplementedError, "String#match needs Regexp class" + end + else + re.match(self, &block) + end end end diff --git a/src/codegen.c b/src/codegen.c index d22892ecf..46d457885 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -1001,7 +1001,9 @@ gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val) } if (val) { genop(s, MKOP_AB(OP_MOVE, cursp(), rhs)); - push(); + } + else { + pop(); } genop(s, MKOP_ABC(OP_APOST, cursp(), n, post)); n = 1; @@ -1016,6 +1018,7 @@ gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val) n++; } } + push(); } } diff --git a/src/error.c b/src/error.c index 0a1a97a0b..29f59ba55 100644 --- a/src/error.c +++ b/src/error.c @@ -454,7 +454,7 @@ mrb_init_exception(mrb_state *mrb) mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */ runtime_error = mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */ - mrb->nomem_err = mrb_obj_ptr(mrb_exc_new_str(mrb, runtime_error, mrb_str_new_lit(mrb, "Out of memory"))); + mrb->nomem_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, runtime_error, "Out of memory")); script_error = mrb_define_class(mrb, "ScriptError", mrb->eException_class); /* 15.2.37 */ mrb_define_class(mrb, "SyntaxError", script_error); /* 15.2.38 */ mrb_define_class(mrb, "SystemStackError", exception); diff --git a/src/kernel.c b/src/kernel.c index cb938f152..485485da5 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -189,12 +189,11 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self) if (ci->proc->env && ci->proc->env->stack) { mrb_value *sp = ci->proc->env->stack; - while (mrb->c->cibase < ci) { - if (ci->stackent == sp) { - break; - } - ci--; - } + /* top-level does not have block slot (alway false) */ + if (sp == mrb->c->stbase) + return mrb_false_value(); + ci = mrb->c->cibase + ci->proc->env->cioff; + bp = ci[1].stackent + 1; } if (ci->argc > 0) { bp += ci->argc; diff --git a/src/string.c b/src/string.c index c602be926..7234fd821 100644 --- a/src/string.c +++ b/src/string.c @@ -1310,7 +1310,7 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str) switch (mrb_type(sub)) { case MRB_TT_FIXNUM: { - int c = mrb_fixnum(sub); + mrb_int c = mrb_fixnum(sub); mrb_int len = RSTRING_LEN(str); unsigned char *p = (unsigned char*)RSTRING_PTR(str); @@ -1656,7 +1656,7 @@ mrb_str_rindex_m(mrb_state *mrb, mrb_value str) switch (mrb_type(sub)) { case MRB_TT_FIXNUM: { - int c = mrb_fixnum(sub); + mrb_int c = mrb_fixnum(sub); unsigned char *p = (unsigned char*)RSTRING_PTR(str); for (pos=len-1;pos>=0;pos--) { diff --git a/tasks/mruby_build_gem.rake b/tasks/mruby_build_gem.rake index 5d2dc030c..dbbade487 100644 --- a/tasks/mruby_build_gem.rake +++ b/tasks/mruby_build_gem.rake @@ -31,7 +31,7 @@ module MRuby return nil unless Gem.current Gem.current.dir = gemdir - Gem.current.build = MRuby::Build.current + Gem.current.build = self.is_a?(MRuby::Build) ? self : MRuby::Build.current Gem.current.build_config_initializer = block gems << Gem.current diff --git a/test/assert.rb b/test/assert.rb index 72e4d3b37..6fad58fa8 100644 --- a/test/assert.rb +++ b/test/assert.rb @@ -228,7 +228,8 @@ def report() t_print("Crash: #{$kill_test}\n") if Object.const_defined?(:Time) - t_print(" Time: #{Time.now - $test_start} seconds\n") + t_time = Time.now - $test_start + t_print(" Time: #{t_time.round(2)} seconds\n") end end diff --git a/test/t/syntax.rb b/test/t/syntax.rb index e7a962441..7ec6272fe 100644 --- a/test/t/syntax.rb +++ b/test/t/syntax.rb @@ -181,6 +181,38 @@ assert('Splat and multiple assignment') do assert_equal [1,nil,2], [a,b,c] end +assert('Splat and multiple assignment from variable') do + a = [1, 2, 3] + b, *c = a + + assert_equal 1, b + assert_equal [2, 3], c +end + +assert('Splat and multiple assignment from variables') do + a = [1, 2, 3] + b = [4, 5, 6, 7] + c, d, *e, f, g = *a, *b + + assert_equal 1, c + assert_equal 2, d + assert_equal [3, 4, 5], e + assert_equal 6, f + assert_equal 7, g +end + +assert('Splat and multiple assignment in for') do + a = [1, 2, 3, 4, 5, 6, 7] + for b, c, *d, e, f in [a] do + end + + assert_equal 1, b + assert_equal 2, c + assert_equal [3, 4, 5], d + assert_equal 6, e + assert_equal 7, f +end + assert('Return values of case statements') do a = [] << case 1 when 3 then 2 diff --git a/tools/mrbc/mrbc.c b/tools/mrbc/mrbc.c index 52e762a50..b51cc4da7 100644 --- a/tools/mrbc/mrbc.c +++ b/tools/mrbc/mrbc.c @@ -9,16 +9,6 @@ #define RITEBIN_EXT ".mrb" #define C_EXT ".c" -#if defined(__cplusplus) -extern "C" { -void mrb_show_version(mrb_state *); -void mrb_show_copyright(mrb_state *); -} -#else -void mrb_show_version(mrb_state *); -void mrb_show_copyright(mrb_state *); -#endif - struct mrbc_args { int argc; char **argv; |
