summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.md4
-rw-r--r--Rakefile6
-rw-r--r--include/mruby.h3
-rw-r--r--include/mruby/khash.h11
-rwxr-xr-xminirake17
-rwxr-xr-xmrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c13
-rwxr-xr-xmrbgems/mruby-bin-debugger/tools/mrdb/apilist.c28
-rwxr-xr-xmrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c2
-rwxr-xr-xmrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c10
-rwxr-xr-xmrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c10
-rw-r--r--mrbgems/mruby-bin-mirb/tools/mirb/mirb.c3
-rw-r--r--mrbgems/mruby-bin-mruby/tools/mruby/mruby.c3
-rw-r--r--mrbgems/mruby-enum-ext/mrblib/enum.rb24
-rw-r--r--mrbgems/mruby-eval/src/eval.c22
-rw-r--r--mrbgems/mruby-string-ext/mrblib/string.rb66
-rw-r--r--mrbgems/mruby-string-ext/test/string.rb69
-rw-r--r--mrbgems/mruby-struct/mrblib/struct.rb31
-rw-r--r--mrbgems/mruby-struct/src/struct.c64
-rw-r--r--mrblib/enum.rb6
-rw-r--r--mrblib/string.rb11
-rw-r--r--src/codegen.c5
-rw-r--r--src/error.c2
-rw-r--r--src/kernel.c11
-rw-r--r--src/string.c4
-rw-r--r--tasks/mruby_build_gem.rake2
-rw-r--r--test/assert.rb3
-rw-r--r--test/t/syntax.rb32
-rw-r--r--tools/mrbc/mrbc.c10
28 files changed, 301 insertions, 171 deletions
diff --git a/README.md b/README.md
index cff98273c..fe23b26a2 100644
--- a/README.md
+++ b/README.md
@@ -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:
diff --git a/Rakefile b/Rakefile
index cc6ded8d0..fee43217c 100644
--- a/Rakefile
+++ b/Rakefile
@@ -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); \
} \
} \
diff --git a/minirake b/minirake
index bdaef0b87..eb219b934 100755
--- a/minirake
+++ b/minirake
@@ -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;