diff options
33 files changed, 305 insertions, 172 deletions
diff --git a/doc/limitations.md b/doc/limitations.md index 1be884b5a..c15b3ba81 100644 --- a/doc/limitations.md +++ b/doc/limitations.md @@ -96,7 +96,7 @@ class Liste < Array def initialize(str = nil) @feld = str end -end +end p Liste.new "foobar" ``` diff --git a/examples/targets/build_config_IntelEdison.rb b/examples/targets/build_config_IntelEdison.rb index 7383f3b4e..8fa3aa0c0 100644 --- a/examples/targets/build_config_IntelEdison.rb +++ b/examples/targets/build_config_IntelEdison.rb @@ -5,12 +5,12 @@ MRuby::Build.new do |conf| toolchain :gcc conf.gembox 'default' - conf.cc.defines = %w(ENABLE_READLINE) + conf.cc.defines = %w(ENABLE_READLINE) conf.gembox 'default' #lightweight regular expression conf.gem :github => "pbosetti/mruby-hs-regexp", :branch => "master" - + end # Define cross build settings @@ -18,7 +18,7 @@ MRuby::CrossBuild.new('core2-32-poky-linux') do |conf| toolchain :gcc # Mac OS X - # + # POKY_EDISON_PATH = '/opt/poky-edison/1.7.2' POKY_EDISON_SYSROOT = "#{POKY_EDISON_PATH}/sysroots/core2-32-poky-linux" @@ -42,7 +42,7 @@ MRuby::CrossBuild.new('core2-32-poky-linux') do |conf| cxx.include_paths << ["#{POKY_EDISON_SYSROOT}/usr/include/c++/4.9.1"] cxx.flags = conf.cc.flags.dup cxx.defines = conf.cc.defines.dup - cxx.compile_options = conf.cc.compile_options.dup + cxx.compile_options = conf.cc.compile_options.dup end conf.archiver do |archiver| diff --git a/include/mruby.h b/include/mruby.h index 5375529dc..1b227d41a 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -222,7 +222,7 @@ MRB_API struct RClass *mrb_define_class(mrb_state *mrb, const char *name, struct /** * Defines a new module. - * + * * @param [mrb_state *] mrb_state* The current mruby state. * @param [const char *] char* The name of the module. * @return [struct RClass *] Reference to the newly defined module. @@ -232,11 +232,11 @@ MRB_API mrb_value mrb_singleton_class(mrb_state*, mrb_value); /** * Include a module in another class or module. - * Equivalent to: + * Equivalent to: * - * module B - * include A - * end + * module B + * include A + * end * @param [mrb_state *] mrb_state* The current mruby state. * @param [struct RClass *] RClass* A reference to module or a class. * @param [struct RClass *] RClass* A reference to the module to be included. @@ -253,7 +253,7 @@ MRB_API void mrb_include_module(mrb_state*, struct RClass*, struct RClass*); * @param [mrb_state *] mrb_state* The current mruby state. * @param [struct RClass *] RClass* A reference to module or a class. * @param [struct RClass *] RClass* A reference to the module to be prepended. - */ + */ MRB_API void mrb_prepend_module(mrb_state*, struct RClass*, struct RClass*); /** @@ -302,7 +302,7 @@ MRB_API void mrb_define_method(mrb_state *mrb, struct RClass *cla, const char *n * foo = mrb_define_class(mrb, "Foo", mrb->object_class); * mrb_define_class_method(mrb, foo, "bar", bar_method, MRB_ARGS_NONE()); * } - * @param [mrb_state *] mrb_state* The MRuby state reference. + * @param [mrb_state *] mrb_state* The MRuby state reference. * @param [struct RClass *] RClass* The class where the class method will be defined. * @param [const char *] char* The name of the class method being defined. * @param [mrb_func_t] mrb_func_t The function pointer to the class method definition. @@ -317,23 +317,23 @@ MRB_API void mrb_define_singleton_method(mrb_state*, struct RObject*, const char * Example: * * # Ruby style - * module Foo + * module Foo * def Foo.bar - * end - * end - * // C style + * end + * end + * // C style * mrb_value bar_method(mrb_state* mrb, mrb_value self){ - * return mrb_nil_value(); - * } - * void mrb_example_gem_init(mrb_state* mrb){ + * return mrb_nil_value(); + * } + * void mrb_example_gem_init(mrb_state* mrb){ * struct RClass *foo; - * foo = mrb_define_module(mrb, "Foo"); + * foo = mrb_define_module(mrb, "Foo"); * mrb_define_module_function(mrb, foo, "bar", bar_method, MRB_ARGS_NONE()); - * } + * } * @param [mrb_state *] mrb_state* The MRuby state reference. * @param [struct RClass *] RClass* The module where the module function will be defined. * @param [const char *] char* The name of the module function being defined. - * @param [mrb_func_t] mrb_func_t The function pointer to the module function definition. + * @param [mrb_func_t] mrb_func_t The function pointer to the module function definition. * @param [mrb_aspec] mrb_aspec The method parameters declaration. */ MRB_API void mrb_define_module_function(mrb_state*, struct RClass*, const char*, mrb_func_t, mrb_aspec); @@ -348,9 +348,9 @@ MRB_API void mrb_define_module_function(mrb_state*, struct RClass*, const char*, * AGE = 22 * end * // C style - * #include <stdio.h> + * #include <stdio.h> * #include <mruby.h> - * + * * void * mrb_example_gem_init(mrb_state* mrb){ * mrb_define_const(mrb, mrb->kernel_module, "AGE", mrb_fixnum_value(22)); @@ -389,7 +389,7 @@ MRB_API void mrb_define_const(mrb_state*, struct RClass*, const char *name, mrb_ * // C style * #include <stdio.h> * #include <mruby.h> - * + * * mrb_value * mrb_example_method(mrb_state *mrb){ * return mrb_str_new_cstr(mrb, "example"); @@ -400,14 +400,14 @@ MRB_API void mrb_define_const(mrb_state*, struct RClass*, const char *name, mrb_ * struct RClass *example_class_a; * struct RClass *example_class_b; * struct RClass *example_class_c; - * + * * example_class_a = mrb_define_class(mrb, "ExampleClassA", mrb->object_class); * mrb_define_method(mrb, example_class_a, "example_method", mrb_example_method, MRB_ARGS_NONE()); * example_class_b = mrb_define_class(mrb, "ExampleClassB", example_class_a); * example_class_c = mrb_define_class(mrb, "ExampleClassC", example_class_b); * mrb_undef_method(mrb, example_class_c, "example_method"); * } - * + * * mrb_example_gem_final(mrb_state* mrb){ * } * @param [mrb_state*] mrb_state* The mruby state reference. @@ -428,16 +428,16 @@ MRB_API void mrb_undef_method(mrb_state*, struct RClass*, const char*); * end * * ExampleClass.example_method - * + * * // C style * #include <stdio.h> - * #include <mruby.h> + * #include <mruby.h> * * mrb_value * mrb_example_method(mrb_state *mrb){ - * return mrb_str_new_cstr(mrb, "example"); + * return mrb_str_new_cstr(mrb, "example"); * } - * + * * void * mrb_example_gem_init(mrb_state* mrb){ * struct RClass *example_class; @@ -445,7 +445,7 @@ MRB_API void mrb_undef_method(mrb_state*, struct RClass*, const char*); * mrb_define_class_method(mrb, example_class, "example_method", mrb_example_method, MRB_ARGS_NONE()); * mrb_undef_class_method(mrb, example_class, "example_method"); * } - * + * * void * mrb_example_gem_final(mrb_state* mrb){ * } @@ -476,7 +476,7 @@ MRB_API void mrb_undef_class_method(mrb_state*, struct RClass*, const char*); * example_class = mrb_define_class(mrb, "ExampleClass", mrb->object_class); # => class ExampleClass; end * obj = mrb_obj_new(mrb, example_class, 0, NULL); # => ExampleClass.new * mrb_p(mrb, obj); // => Kernel#p - * } + * } * @param [mrb_state*] mrb The current mruby state. * @param [RClass*] c Reference to the class of the new object. * @param [mrb_int] argc Number of arguments in argv @@ -501,7 +501,7 @@ MRB_API mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv); * void * mrb_example_gem_init(mrb_state* mrb) { * struct RClass *example_class; - * + * * mrb_value obj; * example_class = mrb_class_new(mrb, mrb->object_class); * obj = mrb_obj_new(mrb, example_class, 0, NULL); // => #<#<Class:0x9a945b8>:0x9a94588> @@ -521,7 +521,7 @@ MRB_API struct RClass * mrb_class_new(mrb_state *mrb, struct RClass *super); * void * mrb_example_gem_init(mrb_state* mrb) { * struct RClass *example_module; - * + * * example_module = mrb_module_new(mrb); * } * @@ -541,7 +541,7 @@ MRB_API struct RClass * mrb_module_new(mrb_state *mrb); * * example_class = mrb_define_class(mrb, "ExampleClass", mrb->object_class); * cd = mrb_class_defined(mrb, "ExampleClass"); - * + * * // If mrb_class_defined returns 1 then puts "True" * // If mrb_class_defined returns 0 then puts "False" * if (cd == 1){ @@ -567,6 +567,37 @@ MRB_API mrb_bool mrb_class_defined(mrb_state *mrb, const char *name); MRB_API struct RClass * mrb_class_get(mrb_state *mrb, const char *name); /** + * Returns an mrb_bool. True if inner class was defined, and false if the inner class was not defined. + * + * Example: + * void + * mrb_example_gem_init(mrb_state* mrb) { + * struct RClass *example_outer, *example_inner; + * mrb_bool cd; + * + * example_outer = mrb_define_module(mrb, "ExampleOuter"); + * + * example_inner = mrb_define_class_under(mrb, example_outer, "ExampleInner", mrb->object_class); + * cd = mrb_class_defined_under(mrb, example_outer, "ExampleInner"); + * + * // If mrb_class_defined_under returns 1 then puts "True" + * // If mrb_class_defined_under returns 0 then puts "False" + * if (cd == 1){ + * puts("True"); + * } + * else { + * puts("False"); + * } + * } + * + * @param [mrb_state*] mrb The current mruby state. + * @param [struct RClass *] outer The name of the outer class. + * @param [const char *] name A string representing the name of the inner class. + * @return [mrb_bool] A boolean value. + */ +MRB_API mrb_bool mrb_class_defined_under(mrb_state *mrb, struct RClass *outer, const char *name); + +/** * Gets a child class. * @param [mrb_state*] mrb The current mruby state. * @param [struct RClass *] outer The name of the parent class. @@ -597,7 +628,7 @@ MRB_API mrb_value mrb_notimplement_m(mrb_state*, mrb_value); * Duplicate an object. * * Equivalent to: - * Object#dup + * Object#dup * @param [mrb_state*] mrb The current mruby state. * @param [mrb_value] obj Object to be duplicate. * @return [mrb_value] The newly duplicated object. @@ -629,7 +660,7 @@ MRB_API mrb_value mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char * mrb_define_method(mrb, example_class, "example_method", exampleMethod, MRB_ARGS_NONE()); * mid = mrb_intern_str(mrb, mrb_str_new_cstr(mrb, "example_method" )); * obj_resp = mrb_obj_respond_to(mrb, example_class, mid); // => 1(true in Ruby world) - * + * * // If mrb_obj_respond_to returns 1 then puts "True" * // If mrb_obj_respond_to returns 0 then puts "False" * if (obj_resp == 1) { @@ -780,13 +811,13 @@ mrb_get_argc(mrb_state *mrb) /* get argc */ * #include <stdio.h> * #include <mruby.h> * #include "mruby/compile.h" - * + * * int * main() * { * mrb_int i = 99; * mrb_state *mrb = mrb_open(); - * + * * if (!mrb) { } * FILE *fp = fopen("test.rb","r"); * mrb_value obj = mrb_load_file(mrb,fp); @@ -804,7 +835,7 @@ mrb_get_argc(mrb_state *mrb) /* get argc */ MRB_API mrb_value mrb_funcall(mrb_state*, mrb_value, const char*, mrb_int,...); /** * Call existing ruby functions. This is basically the type safe version of mrb_funcall. - * + * * #include <stdio.h> * #include <mruby.h> * #include "mruby/compile.h" @@ -813,10 +844,10 @@ MRB_API mrb_value mrb_funcall(mrb_state*, mrb_value, const char*, mrb_int,...); * { * mrb_int i = 99; * mrb_state *mrb = mrb_open(); - * + * * if (!mrb) { } * mrb_sym m_sym = mrb_intern_cstr(mrb, "method_name"); // Symbol for method. - * + * * FILE *fp = fopen("test.rb","r"); * mrb_value obj = mrb_load_file(mrb,fp); * mrb_funcall_argv(mrb, obj, m_sym, 1, &obj); // Calling ruby function from test.rb. @@ -841,7 +872,7 @@ MRB_API mrb_value mrb_funcall_with_block(mrb_state*, mrb_value, mrb_sym, mrb_int * * # Ruby style: * :pizza # => :pizza - * + * * // C style: * mrb_sym m_sym = mrb_intern_cstr(mrb, "pizza"); // => :pizza * @param [mrb_state*] mrb_state* The current mruby state. diff --git a/include/mruby/string.h b/include/mruby/string.h index c4af0963e..e45846e87 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -91,12 +91,12 @@ MRB_API void mrb_str_modify(mrb_state*, struct RString*); /* * Appends self to other. Returns self as a concatnated string. * - * + * * Example: * * !!!c * int - * main(int argc, + * main(int argc, * char **argv) * { * // Variable declarations. @@ -138,12 +138,12 @@ MRB_API void mrb_str_concat(mrb_state*, mrb_value, mrb_value); /* * Adds two strings together. * - * + * * Example: * * !!!c * int - * main(int argc, + * main(int argc, * char **argv) * { * // Variable declarations. @@ -215,7 +215,7 @@ MRB_API mrb_value mrb_obj_as_string(mrb_state *mrb, mrb_value obj); * * !!!c * int - * main(int argc, + * main(int argc, * char **argv) * { * // Variable declaration. @@ -224,11 +224,11 @@ MRB_API mrb_value mrb_obj_as_string(mrb_state *mrb, mrb_value obj); * mrb_state *mrb = mrb_open(); * if (!mrb) * { - * // handle error + * // handle error * } * // Creates a new string. * str = mrb_str_new_cstr(mrb, "Hello, world!"); - * // Returns 5 characters of + * // Returns 5 characters of * mrb_str_resize(mrb, str, 5); * mrb_p(mrb, str); * @@ -254,7 +254,7 @@ MRB_API mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len); * * !!!c * int - * main(int argc, + * main(int argc, * char const **argv) * { * // Variable declarations. diff --git a/mrbgems/mruby-array-ext/mrblib/array.rb b/mrbgems/mruby-array-ext/mrblib/array.rb index 04637471d..1e6d4d581 100644 --- a/mrbgems/mruby-array-ext/mrblib/array.rb +++ b/mrbgems/mruby-array-ext/mrblib/array.rb @@ -275,8 +275,9 @@ class Array # +default+ value. # # Alternatively, if a block is given it will only be executed when an - # invalid +index+ is referenced. Negative values of +index+ count from the - # end of the array. + # invalid +index+ is referenced. + # + # Negative values of +index+ count from the end of the array. # # a = [ 11, 22, 33, 44 ] # a.fetch(1) #=> 22 diff --git a/mrbgems/mruby-bin-debugger/bintest/mrdb.rb b/mrbgems/mruby-bin-debugger/bintest/mrdb.rb index ae40f0a46..26f3138aa 100644 --- a/mrbgems/mruby-bin-debugger/bintest/mrdb.rb +++ b/mrbgems/mruby-bin-debugger/bintest/mrdb.rb @@ -14,7 +14,7 @@ class BinTest_MrubyBinDebugger # compile `./bin/mrbc -g -o "#{bin.path}" "#{script.path}"` - + # add mrdb quit testcase << {:cmd=>"quit"} diff --git a/mrbgems/mruby-bin-debugger/bintest/print.rb b/mrbgems/mruby-bin-debugger/bintest/print.rb index e9d85f333..403ada8e1 100644 --- a/mrbgems/mruby-bin-debugger/bintest/print.rb +++ b/mrbgems/mruby-bin-debugger/bintest/print.rb @@ -13,7 +13,7 @@ class BinTest_MrubyBinDebugger # compile `./bin/mrbc -g -o "#{bin.path}" "#{script.path}"` - + # add mrdb quit testcase << {:cmd=>"quit"} diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c b/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c index 67b4e8422..218aeda90 100644 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c @@ -97,7 +97,7 @@ check_file_lineno( struct mrb_irep *irep, const char *file, uint16_t lineno ) result = MRB_DEBUG_BP_FILE_OK; fix_lineno = check_lineno( info_file, lineno ); - if(fix_lineno != 0) { + if(fix_lineno != 0) { return result | MRB_DEBUG_BP_LINENO_OK; } } @@ -200,7 +200,7 @@ mrb_debug_set_break_line( mrb_state *mrb, mrb_debug_context *dbg, const char *fi return MRB_DEBUG_BREAK_INVALID_FILE; }else if(result == MRB_DEBUG_BP_FILE_OK) { return MRB_DEBUG_BREAK_INVALID_LINENO; - } + } set_file = mrb_malloc(mrb, strlen(file) + 1); @@ -272,7 +272,7 @@ mrb_debug_get_breaknum( mrb_state *mrb, mrb_debug_context *dbg ) return dbg->bpnum; } -int32_t +int32_t mrb_debug_get_break_all( mrb_state *mrb, mrb_debug_context *dbg, uint32_t size, mrb_debug_breakpoint *bp ) { uint32_t get_size = 0; @@ -315,7 +315,7 @@ mrb_debug_get_break( mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno, mrb_ return 0; } -int32_t +int32_t mrb_debug_delete_break( mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno ) { uint32_t i; @@ -346,7 +346,7 @@ mrb_debug_delete_break( mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno ) return MRB_DEBUG_OK; } -int32_t +int32_t mrb_debug_delete_break_all( mrb_state *mrb, mrb_debug_context *dbg ) { uint32_t i; @@ -364,7 +364,7 @@ mrb_debug_delete_break_all( mrb_state *mrb, mrb_debug_context *dbg ) return MRB_DEBUG_OK; } -int32_t +int32_t mrb_debug_enable_break( mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno ) { int32_t index = 0; @@ -399,7 +399,7 @@ mrb_debug_enable_break_all( mrb_state *mrb, mrb_debug_context *dbg ) return MRB_DEBUG_OK; } -int32_t +int32_t mrb_debug_disable_break( mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno ) { int32_t index = 0; @@ -418,7 +418,7 @@ mrb_debug_disable_break( mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno ) return MRB_DEBUG_OK; } -int32_t +int32_t mrb_debug_disable_break_all( mrb_state *mrb, mrb_debug_context *dbg ) { uint32_t i; @@ -483,7 +483,7 @@ mrb_debug_check_breakpoint_line( mrb_state *mrb, mrb_debug_context *dbg, const c } -int32_t +int32_t mrb_debug_check_breakpoint_method( mrb_state *mrb, mrb_debug_context *dbg, struct RClass *class_obj, mrb_sym method_sym, mrb_bool* isCfunc ) { mrb_debug_breakpoint *bp; diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c b/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c index 2030c08b6..171c6a0f7 100644 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c @@ -22,7 +22,7 @@ dbgcmd_run(mrb_state *mrb, mrdb_state *mrdb) mrb_raise(mrb, exc, "Restart mrdb."); } } - + return DBGST_RESTART; } diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c b/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c index d1d02bd40..04503dcf9 100644 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c @@ -691,7 +691,7 @@ main(int argc, char **argv) } mrdb->dbg->xm = DBG_INIT; mrdb->dbg->ccnt = 1; - + /* setup hook functions */ mrb->code_fetch_hook = mrb_code_fetch_hook; mrdb->dbg->break_hook = mrb_debug_break_hook; @@ -738,21 +738,21 @@ main(int argc, char **argv) mrb_p(mrb, v); } } - + mrdb->dbg->prvfile = "-"; mrdb->dbg->prvline = 0; - + while (1) { cmd = get_and_parse_command(mrb, mrdb); mrb_assert(cmd); - + if (cmd->id == DBGCMD_QUIT) { break; } - + if( cmd->func(mrb, mrdb) == DBGST_RESTART ) goto l_restart; } - + cleanup(mrb, &args); return 0; diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index efdd77888..9b064b867 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -1645,7 +1645,7 @@ codegen(codegen_scope *s, node *tree, int val) node *t = tree->cdr, *p; int rhs = cursp(); - if ((intptr_t)t->car == NODE_ARRAY && nosplat(t->cdr)) { + if ((intptr_t)t->car == NODE_ARRAY && t->cdr && nosplat(t->cdr)) { /* fixed rhs */ t = t->cdr; while (t) { @@ -1655,11 +1655,21 @@ codegen(codegen_scope *s, node *tree, int val) } tree = tree->car; if (tree->car) { /* pre */ + int first = TRUE; t = tree->car; n = 0; while (t) { - gen_assignment(s, t->car, rhs+n, NOVAL); - n++; + if (n < len) { + gen_assignment(s, t->car, rhs+n, NOVAL); + n++; + } + else { + if (first) { + genop(s, MKOP_A(OP_LOADNIL, rhs+n)); + first = FALSE; + } + gen_assignment(s, t->car, rhs+n, NOVAL); + } t = t->cdr; } } diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index 22d31a390..90b8812b9 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -1089,7 +1089,7 @@ heredoc_end(parser_state *p) %token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL %token <nd> tINTEGER tFLOAT tCHAR tXSTRING tREGEXP -%token <nd> tSTRING tSTRING_PART tSTRING_MID +%token <nd> tSTRING tSTRING_PART tSTRING_MID tLABEL_END %token <nd> tNTH_REF tBACK_REF %token <num> tREGEXP_END @@ -2972,7 +2972,7 @@ superclass : /* term */ expr_value term { $$ = $3; - } /* + } /* | error term { yyerrok; @@ -3241,6 +3241,18 @@ assoc : arg_value tASSOC arg_value { $$ = cons(new_sym(p, $1), $2); } + | tLABEL_END arg_value + { + $$ = cons(new_sym(p, new_strsym(p, $1)), $2); + } + | tSTRING_BEG tLABEL_END arg_value + { + $$ = cons(new_sym(p, new_strsym(p, $2)), $3); + } + | tSTRING_BEG string_rep tLABEL_END arg_value + { + $$ = cons(new_dsym(p, push($2, $3)), $4); + } ; operation : tIDENTIFIER @@ -3895,6 +3907,8 @@ parse_string(parser_state *p) int end = (intptr_t)p->lex_strterm->cdr->cdr->cdr; parser_heredoc_info *hinf = (type & STR_FUNC_HEREDOC) ? parsing_heredoc_inf(p) : NULL; + if (beg == 0) beg = -3; /* should never happen */ + if (end == 0) end = -3; newtok(p); while ((c = nextc(p)) != end || nest_level != 0) { if (hinf && (c == '\n' || c < 0)) { @@ -4080,8 +4094,13 @@ parse_string(parser_state *p) return tREGEXP; } - yylval.nd = new_str(p, tok(p), toklen(p)); + if (IS_LABEL_SUFFIX(0)) { + p->lstate = EXPR_BEG; + nextc(p); + return tLABEL_END; + } + return tSTRING; } @@ -5460,7 +5479,10 @@ mrb_parser_parse(parser_state *p, mrbc_context *c) p->lex_strterm = NULL; parser_init_cxt(p, c); - yyparse(p); + if (yyparse(p) != 0 || p->nerr > 0) { + p->tree = 0; + return; + } if (!p->tree) { p->tree = new_nil(p); } @@ -6487,7 +6509,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) break; case NODE_HEREDOC: - printf("NODE_HEREDOC:\n"); + printf("NODE_HEREDOC (<<%s):\n", ((parser_heredoc_info*)tree)->term); mrb_parser_dump(mrb, ((parser_heredoc_info*)tree)->doc, offset+1); break; diff --git a/mrbgems/mruby-enum-ext/mrblib/enum.rb b/mrbgems/mruby-enum-ext/mrblib/enum.rb index a5f661ce6..6724dff37 100644 --- a/mrbgems/mruby-enum-ext/mrblib/enum.rb +++ b/mrbgems/mruby-enum-ext/mrblib/enum.rb @@ -573,35 +573,38 @@ module Enumerable # a.cycle(2) { |x| puts x } # print, a, b, c, a, b, c. # - def cycle(n=nil, &block) - return to_enum(:cycle, n) if !block && n.nil? + def cycle(nv = nil, &block) + return to_enum(:cycle, nv) unless block - ary = [] - if n.nil? - self.each do|*val| - ary.push val - block.call(*val) + n = nil + + if nv.nil? + n = -1 + else + unless nv.respond_to?(:to_int) + raise TypeError, "no implicit conversion of #{nv.class} into Integer" end - loop do - ary.each do|e| - block.call(*e) - end + n = nv.to_int + unless n.kind_of?(Integer) + raise TypeError, "no implicit conversion of #{nv.class} into Integer" end - else - raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int) + return nil if n <= 0 + end - n = n.to_int - self.each do|*val| - ary.push val - end - count = 0 - while count < n - ary.each do|e| - block.call(*e) - end - count += 1 + ary = [] + each do |*i| + ary.push(i) + yield(*i) + end + return nil if ary.empty? + + while n < 0 || 0 < (n -= 1) + ary.each do |i| + yield(*i) end end + + nil end ## diff --git a/mrbgems/mruby-enum-ext/test/enum.rb b/mrbgems/mruby-enum-ext/test/enum.rb index 08b553fe5..076562f45 100644 --- a/mrbgems/mruby-enum-ext/test/enum.rb +++ b/mrbgems/mruby-enum-ext/test/enum.rb @@ -128,6 +128,13 @@ assert("Enumerable#cycle") do ["a", "b", "c"].cycle(2) { |v| a << v } assert_equal ["a", "b", "c", "a", "b", "c"], a assert_raise(TypeError) { ["a", "b", "c"].cycle("a") { |v| a << v } } + + empty = Class.new do + include Enumerable + def each + end + end + assert_nil empty.new.cycle { break :nope } end assert("Enumerable#find_index") do diff --git a/mrbgems/mruby-error/test/exception.rb b/mrbgems/mruby-error/test/exception.rb index 0bbc2a0e7..908465045 100644 --- a/mrbgems/mruby-error/test/exception.rb +++ b/mrbgems/mruby-error/test/exception.rb @@ -5,7 +5,7 @@ assert 'mrb_protect' do end # failure in protect returns [exception, true] result = ExceptionTest.mrb_protect { raise 'test' } - assert_kind_of RuntimeError, result[0] + assert_kind_of RuntimeError, result[0] assert_true result[1] end diff --git a/mrbgems/mruby-kernel-ext/src/kernel.c b/mrbgems/mruby-kernel-ext/src/kernel.c index 74aa555d0..d2153be4a 100644 --- a/mrbgems/mruby-kernel-ext/src/kernel.c +++ b/mrbgems/mruby-kernel-ext/src/kernel.c @@ -61,7 +61,7 @@ mrb_f_integer(mrb_state *mrb, mrb_value self) * Float(arg) -> float * * Returns <i>arg</i> converted to a float. Numeric types are converted - * directly, the rest are converted using <i>arg</i>.to_f. + * directly, the rest are converted using <i>arg</i>.to_f. * * Float(1) #=> 1.0 * Float(123.456) #=> 123.456 diff --git a/mrbgems/mruby-random/src/mt19937ar.h b/mrbgems/mruby-random/src/mt19937ar.h index 31e5d19ed..7d382320d 100644 --- a/mrbgems/mruby-random/src/mt19937ar.h +++ b/mrbgems/mruby-random/src/mt19937ar.h @@ -28,7 +28,7 @@ ** Any feedback is very welcome. ** http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html ** email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) -** +** ** This version is modified by mruby developers. If you see any problem, ** contact us first at https://github.com/mruby/mruby/issues */ diff --git a/mrbgems/mruby-string-ext/mrblib/string.rb b/mrbgems/mruby-string-ext/mrblib/string.rb index a291b8207..c3b765a5f 100644 --- a/mrbgems/mruby-string-ext/mrblib/string.rb +++ b/mrbgems/mruby-string-ext/mrblib/string.rb @@ -207,7 +207,7 @@ class String else idx = arg1 idx += self.size if arg1 < 0 - validated = true if idx >=0 && arg1 < self.size + validated = true if idx >=0 && arg1 < self.size end if validated str = self[arg1] diff --git a/mrblib/hash.rb b/mrblib/hash.rb index 782111459..4727b0870 100644 --- a/mrblib/hash.rb +++ b/mrblib/hash.rb @@ -201,7 +201,7 @@ class Hash }.join(", ")+"}" end ## - # Return the contents of this hash as a string. + # Return the contents of this hash as a string. # # ISO 15.2.13.4.30 (x) def inspect diff --git a/src/class.c b/src/class.c index 00fc9c12e..7097a593a 100644 --- a/src/class.c +++ b/src/class.c @@ -271,6 +271,16 @@ mrb_class_defined(mrb_state *mrb, const char *name) return mrb_const_defined(mrb, mrb_obj_value(mrb->object_class), mrb_symbol(sym)); } +MRB_API mrb_bool +mrb_class_defined_under(mrb_state *mrb, struct RClass *outer, const char *name) +{ + mrb_value sym = mrb_check_intern_cstr(mrb, name); + if (mrb_nil_p(sym)) { + return FALSE; + } + return mrb_const_defined_at(mrb, mrb_obj_value(outer), mrb_symbol(sym)); +} + MRB_API struct RClass * mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name) { diff --git a/src/fmt_fp.c b/src/fmt_fp.c index 61c7a4cc9..483e04c39 100644 --- a/src/fmt_fp.c +++ b/src/fmt_fp.c @@ -253,7 +253,7 @@ fmt_fp(struct fmt_args *f, long double y, int w, int p, int fl, int t) if (z>d+1) z=d+1; } for (; z>a && !z[-1]; z--); - + if ((t|32)=='g') { if (!p) p++; if (p>e && e>=-4) { @@ -354,7 +354,7 @@ fmt_core(struct fmt_args *f, const char *fmt, mrb_float flo) return fmt_fp(f, flo, 0, p, 0, *fmt); default: return -1; - } + } } mrb_value @@ -65,7 +65,7 @@ mruby implementer and C extension library writer must insert a write barrier when updating a reference from a field of an object. - When updating a reference from a field of object A to object B, + When updating a reference from a field of object A to object B, two different types of write barrier are available: * mrb_field_write_barrier - target B object for a mark. @@ -736,7 +736,8 @@ obj_free(mrb_state *mrb, struct RBasic *obj) while (ce <= ci) { struct REnv *e = ci->env; - if (e && !is_dead(&mrb->gc, e) && MRB_ENV_STACK_SHARED_P(e)) { + if (e && !is_dead(&mrb->gc, e) && + e->tt == MRB_TT_ENV && MRB_ENV_STACK_SHARED_P(e)) { mrb_env_unshare(mrb, e); } ci--; diff --git a/src/kernel.c b/src/kernel.c index 54b5f23b6..df237cd46 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -960,10 +960,11 @@ obj_respond_to(mrb_state *mrb, mrb_value self) if (!respond_to_p) { rtm_id = mrb_intern_lit(mrb, "respond_to_missing?"); if (basic_obj_respond_to(mrb, self, rtm_id, !priv)) { - mrb_value args[2]; + mrb_value args[2], v; args[0] = mid; args[1] = mrb_bool_value(priv); - return mrb_funcall_argv(mrb, self, rtm_id, 2, args); + v = mrb_funcall_argv(mrb, self, rtm_id, 2, args); + return mrb_bool_value(mrb_bool(v)); } } return mrb_bool_value(respond_to_p); diff --git a/src/load.c b/src/load.c index 18b1d3713..4a0dcb0e8 100644 --- a/src/load.c +++ b/src/load.c @@ -523,7 +523,7 @@ read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc, uint8_t if (memcmp(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident)) == 0) { if (bigendian_p()) *flags |= FLAG_BYTEORDER_NATIVE; - else + else *flags |= FLAG_BYTEORDER_BIG; } else if (memcmp(header->binary_ident, RITE_BINARY_IDENT_LIL, sizeof(header->binary_ident)) == 0) { diff --git a/src/numeric.c b/src/numeric.c index 85847284e..327d54177 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -55,7 +55,7 @@ num_pow(mrb_state *mrb, mrb_value x) mrb_get_args(mrb, "o", &y); yv = mrb_to_flo(mrb, y); d = pow(mrb_to_flo(mrb, x), yv); - if (mrb_fixnum_p(x) && mrb_fixnum_p(y) && FIXABLE(d) && yv > 0 && + if (mrb_fixnum_p(x) && mrb_fixnum_p(y) && FIXABLE(d) && yv > 0 && (d < 0 || (d > 0 && (mrb_int)d > 0))) return mrb_fixnum_value((mrb_int)d); return mrb_float_value(mrb, d); diff --git a/src/range.c b/src/range.c index bc8b11419..079a1035e 100644 --- a/src/range.c +++ b/src/range.c @@ -152,7 +152,7 @@ mrb_range_eq(mrb_state *mrb, mrb_value range) { struct RRange *rr; struct RRange *ro; - mrb_value obj; + mrb_value obj, v1, v2; mrb_get_args(mrb, "o", &obj); @@ -163,9 +163,9 @@ mrb_range_eq(mrb_state *mrb, mrb_value range) rr = mrb_range_ptr(range); ro = mrb_range_ptr(obj); - if (!mrb_bool(mrb_funcall(mrb, rr->edges->beg, "==", 1, ro->edges->beg)) || - !mrb_bool(mrb_funcall(mrb, rr->edges->end, "==", 1, ro->edges->end)) || - rr->excl != ro->excl) { + v1 = mrb_funcall(mrb, rr->edges->beg, "==", 1, ro->edges->beg); + v2 = mrb_funcall(mrb, rr->edges->end, "==", 1, ro->edges->end); + if (!mrb_bool(v1) || !mrb_bool(v2) || rr->excl != ro->excl) { return mrb_false_value(); } return mrb_true_value(); diff --git a/src/variable.c b/src/variable.c index 3b5674923..29f43e69d 100644 --- a/src/variable.c +++ b/src/variable.c @@ -760,13 +760,15 @@ mrb_mod_cv_get(mrb_state *mrb, struct RClass * c, mrb_sym sym) { struct RClass * cls = c; mrb_value v; + int given = FALSE; while (c) { if (c->iv && iv_get(mrb, c->iv, sym, &v)) { - return v; + given = TRUE; } c = c->super; } + if (given) return v; if (cls && cls->tt == MRB_TT_SCLASS) { mrb_value klass; @@ -774,12 +776,14 @@ mrb_mod_cv_get(mrb_state *mrb, struct RClass * c, mrb_sym sym) mrb_intern_lit(mrb, "__attached__")); c = mrb_class_ptr(klass); if (c->tt == MRB_TT_CLASS || c->tt == MRB_TT_MODULE) { + given = FALSE; while (c) { if (c->iv && iv_get(mrb, c->iv, sym, &v)) { - return v; + given = TRUE; } c = c->super; } + if (given) return v; } } mrb_name_error(mrb, sym, "uninitialized class variable %S in %S", @@ -1094,14 +1094,22 @@ RETRY_TRY_BLOCK: mrb_callinfo *ci; mrb_value recv, result; mrb_sym mid = syms[GETARG_B(i)]; + int bidx; recv = regs[a]; + if (n == CALL_MAXARGS) { + bidx = a+2; + } + else { + bidx = a+n+1; + } if (GET_OPCODE(i) != OP_SENDB) { - if (n == CALL_MAXARGS) { - SET_NIL_VALUE(regs[a+2]); - } - else { - SET_NIL_VALUE(regs[a+n+1]); + SET_NIL_VALUE(regs[bidx]); + } + else { + mrb_value blk = regs[bidx]; + if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) { + regs[bidx] = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); } } c = mrb_class(mrb, recv); @@ -1420,9 +1428,6 @@ RETRY_TRY_BLOCK: int len = m1 + o + r + m2; mrb_value *blk = &argv[argc < 0 ? 1 : argc]; - if (!mrb_nil_p(*blk) && mrb_type(*blk) != MRB_TT_PROC) { - *blk = mrb_convert_type(mrb, *blk, MRB_TT_PROC, "Proc", "to_proc"); - } if (argc < 0) { struct RArray *ary = mrb_ary_ptr(regs[1]); argv = ary->ptr; @@ -1508,6 +1513,7 @@ RETRY_TRY_BLOCK: /* A B return R(A) (B=normal,in-block return/break) */ if (mrb->exc) { mrb_callinfo *ci; + mrb_value *stk; int eidx; L_RAISE: @@ -1519,6 +1525,7 @@ RETRY_TRY_BLOCK: if (ci->ridx == 0) goto L_STOP; goto L_RESCUE; } + stk = mrb->c->stack; while (ci[0].ridx == ci[-1].ridx) { cipop(mrb); ci = mrb->c->ci; @@ -1528,6 +1535,7 @@ RETRY_TRY_BLOCK: MRB_THROW(prev_jmp); } if (ci == mrb->c->cibase) { + mrb->c->stack = stk; while (eidx > 0) { ecall(mrb, --eidx); } @@ -2293,6 +2301,9 @@ RETRY_TRY_BLOCK: mrb_value recv = regs[a]; struct RProc *p; + /* prepare closure */ + p = mrb_closure_new(mrb, irep->reps[GETARG_Bx(i)]); + /* prepare stack */ ci = cipush(mrb); ci->pc = pc + 1; @@ -2305,7 +2316,7 @@ RETRY_TRY_BLOCK: /* prepare stack */ mrb->c->stack += a; - p = mrb_proc_new(mrb, irep->reps[GETARG_Bx(i)]); + /* setup closure */ p->target_class = ci->target_class; ci->proc = p; diff --git a/tasks/mrbgem_spec.rake b/tasks/mrbgem_spec.rake index ec132eab2..78d912980 100644 --- a/tasks/mrbgem_spec.rake +++ b/tasks/mrbgem_spec.rake @@ -18,7 +18,7 @@ module MRuby alias mruby build attr_accessor :build_config_initializer attr_accessor :mrblib_dir, :objs_dir - + attr_accessor :version attr_accessor :description, :summary attr_accessor :homepage diff --git a/tasks/toolchains/android.rake b/tasks/toolchains/android.rake index 376185762..0cc60a7a3 100644 --- a/tasks/toolchains/android.rake +++ b/tasks/toolchains/android.rake @@ -5,17 +5,21 @@ class MRuby::Toolchain::Android DEFAULT_TOOLCHAIN = :clang DEFAULT_NDK_HOMES = %w{ - /usr/local/opt/android-ndk /usr/local/opt/android-sdk/ndk-bundle + /usr/local/opt/android-ndk %LOCALAPPDATA%/Android/android-sdk/ndk-bundle + %LOCALAPPDATA%/Android/android-ndk + ~/Library/Android/sdk/ndk-bundle + ~/Library/Android/ndk } - TOOLCHAINS = [:clang] # TODO : Add gcc support + TOOLCHAINS = [:clang, :gcc] ARCHITECTURES = %w{ armeabi armeabi-v7a arm64-v8a x86 x86_64 - } # TODO : Add mips mips64 support + mips mips64 + } class AndroidNDKHomeNotFound < StandardError def message @@ -42,42 +46,18 @@ Set ANDROID_PLATFORM environment variable or set :platform parameter end def bin_gcc(command) - case toolchain - when :gcc then bin(command) - when :clang - command = command.to_s - - command = case arch - when /armeabi/ then 'arm-linux-androideabi-' - when /arm64-v8a/ then 'aarch64-linux-android-' - when /x86_64/ then 'x86_64-linux-android-' - when /x86/ then 'i686-linux-android-' - when /mips64/ then 'mips64el-linux-android-' - when /mips/ then 'mipsel-linux-android-' - end + command - - prefix = case arch - when /armeabi/ then 'arm-linux-androideabi-' - when /arm64-v8a/ then 'aarch64-linux-android-' - when /x86_64/ then 'x86_64-' - when /x86/ then 'x86-' - when /mips64/ then 'mips64el-linux-android-' - when /mips/ then 'mipsel-linux-android-' - end + command = command.to_s - test = case arch - when /armeabi/ then 'arm-linux-androideabi-*' - when /arm64-v8a/ then 'aarch64-linux-android-*' - when /x86_64/ then 'x86_64-*' - when /x86/ then 'x86-*' - when /mips64/ then 'mips64el-linux-android-*' - when /mips/ then 'mipsel-linux-android-*' - end + command = case arch + when /armeabi/ then 'arm-linux-androideabi-' + when /arm64-v8a/ then 'aarch64-linux-android-' + when /x86_64/ then 'x86_64-linux-android-' + when /x86/ then 'i686-linux-android-' + when /mips64/ then 'mips64el-linux-android-' + when /mips/ then 'mipsel-linux-android-' + end + command - gcc_toolchain_version = Dir[home_path.join('toolchains', test)].map{|t| t.match(/-(\d+\.\d+)$/); $1.to_f }.max - gcc_toolchain_path = home_path.join('toolchains', prefix + gcc_toolchain_version.to_s, 'prebuilt', host_platform) - gcc_toolchain_path.join('bin', command).to_s - end + gcc_toolchain_path.join('bin', command).to_s end def bin(command) @@ -92,6 +72,7 @@ Set ANDROID_PLATFORM environment variable or set :platform parameter DEFAULT_NDK_HOMES.find { |path| path.gsub! '%LOCALAPPDATA%', ENV['LOCALAPPDATA'] || '%LOCALAPPDATA%' path.gsub! '\\', '/' + path.gsub! '~', Dir.home || '~' File.directory?(path) } || raise(AndroidNDKHomeNotFound) ) @@ -103,11 +84,39 @@ Set ANDROID_PLATFORM environment variable or set :platform parameter def toolchain_path @toolchain_path ||= case toolchain + when :gcc + gcc_toolchain_path when :clang home_path.join('toolchains', 'llvm' , 'prebuilt', host_platform) end end + def gcc_toolchain_path + if @gcc_toolchain_path === nil then + prefix = case arch + when /armeabi/ then 'arm-linux-androideabi-' + when /arm64-v8a/ then 'aarch64-linux-android-' + when /x86_64/ then 'x86_64-' + when /x86/ then 'x86-' + when /mips64/ then 'mips64el-linux-android-' + when /mips/ then 'mipsel-linux-android-' + end + + test = case arch + when /armeabi/ then 'arm-linux-androideabi-*' + when /arm64-v8a/ then 'aarch64-linux-android-*' + when /x86_64/ then 'x86_64-*' + when /x86/ then 'x86-*' + when /mips64/ then 'mips64el-linux-android-*' + when /mips/ then 'mipsel-linux-android-*' + end + + gcc_toolchain_version = Dir[home_path.join('toolchains', test)].map{|t| t.match(/-(\d+\.\d+)$/); $1.to_f }.max + @gcc_toolchain_path = home_path.join('toolchains', prefix + gcc_toolchain_version.to_s, 'prebuilt', host_platform) + end + @gcc_toolchain_path + end + def host_platform @host_platform ||= case RUBY_PLATFORM when /cygwin|mswin|mingw|bccwin|wince|emx/i @@ -179,12 +188,14 @@ Set ANDROID_PLATFORM environment variable or set :platform parameter def cc case toolchain + when :gcc then bin_gcc('gcc') when :clang then bin('clang') end end def ar case toolchain + when :gcc then bin_gcc('ar') when :clang then bin_gcc('ar') end end @@ -194,8 +205,19 @@ Set ANDROID_PLATFORM environment variable or set :platform parameter flags += %W(-D__android__ --sysroot="#{sysroot}") case toolchain + when :gcc + flags += %W(-mandroid) + case arch + when /armeabi-v7a/ then flags += %W(-march=armv7-a) + when /armeabi/ then flags += %W(-march=armv5te) + when /arm64-v8a/ then flags += %W(-march=armv8-a) + when /x86_64/ then flags += %W(-march=x86-64) + when /x86/ then flags += %W(-march=i686) + when /mips64/ then flags += %W(-march=mips64) + when /mips/ then flags += %W(-march=mips32) + end when :clang - flags += %W(-gcc-toolchain #{toolchain_path.to_s}) + flags += %W(-gcc-toolchain "#{gcc_toolchain_path.to_s}") case arch when /armeabi-v7a/ then flags += %W(-target armv7-none-linux-androideabi) when /armeabi/ then flags += %W(-target armv5te-none-linux-androideabi) diff --git a/test/assert.rb b/test/assert.rb index e8368c64c..f565652b1 100644 --- a/test/assert.rb +++ b/test/assert.rb @@ -213,7 +213,7 @@ def report() t_print("\n") $asserts.each do |msg| - puts msg + t_print "#{msg}\n" end $total_test = $ok_test+$ko_test+$kill_test diff --git a/test/t/exception.rb b/test/t/exception.rb index 839250ea8..2dc8f5487 100644 --- a/test/t/exception.rb +++ b/test/t/exception.rb @@ -338,10 +338,13 @@ assert('Exception 19') do begin 1 * "b" ensure - @e = self.z + @e = self.zz end end + def zz + true + end def z true end diff --git a/test/t/symbol.rb b/test/t/symbol.rb index b0252849d..9059f45c2 100644 --- a/test/t/symbol.rb +++ b/test/t/symbol.rb @@ -1,6 +1,13 @@ ## # Symbol ISO Test +assert('Symbol') do + assert_equal :"a", :a + assert_equal :"a#{1}", :a1 + assert_equal :'a', :a + assert_equal :'a#{1}', :"a\#{1}" +end + assert('Symbol', '15.2.11') do assert_equal Class, Symbol.class end |
