diff options
| -rw-r--r-- | include/mruby/variable.h | 1 | ||||
| -rwxr-xr-x | minirake | 2 | ||||
| -rw-r--r-- | mrblib/string.rb | 4 | ||||
| -rw-r--r-- | src/class.c | 88 | ||||
| -rw-r--r-- | src/variable.c | 9 | ||||
| -rw-r--r-- | test/assert.rb | 42 | ||||
| -rw-r--r-- | test/t/module.rb | 22 | ||||
| -rw-r--r-- | test/t/string.rb | 8 | ||||
| -rw-r--r-- | tools/mirb/mirb.c | 4 |
9 files changed, 126 insertions, 54 deletions
diff --git a/include/mruby/variable.h b/include/mruby/variable.h index f2f22e65a..a1f52217d 100644 --- a/include/mruby/variable.h +++ b/include/mruby/variable.h @@ -37,6 +37,7 @@ void mrb_vm_const_set(mrb_state*, mrb_sym, mrb_value); mrb_value mrb_const_get(mrb_state*, mrb_value, mrb_sym); void mrb_const_set(mrb_state*, mrb_value, mrb_sym, mrb_value); int mrb_const_defined(mrb_state*, mrb_value, mrb_sym); +void mrb_const_remove(mrb_state*, mrb_value, mrb_sym); mrb_value mrb_obj_iv_get(mrb_state *mrb, struct RObject *obj, mrb_sym sym); void mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v); @@ -287,7 +287,7 @@ module MiniRake end Rake = MiniRake -include MiniRake::DSL +extend MiniRake::DSL ###################################################################### diff --git a/mrblib/string.rb b/mrblib/string.rb index 9b11bb2e5..8a4894dd4 100644 --- a/mrblib/string.rb +++ b/mrblib/string.rb @@ -28,8 +28,10 @@ class String # # ISO 15.2.10.5.18 def gsub(*args, &block) + lc = '' if args.size == 2 - split(args[0]).join(args[1]) + lc = args[1] if self[-1] == args[0] + split(args[0]).join(args[1]) + lc elsif args.size == 1 && block split(args[0]).join(block.call(args[0])) else diff --git a/src/class.c b/src/class.c index 136a07cb6..e70bd7e73 100644 --- a/src/class.c +++ b/src/class.c @@ -600,9 +600,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) if (mrb_type(ss) == MRB_TT_SYMBOL) { *symp = mrb_symbol(ss); } - else { + else if (mrb_string_p(ss)) { *symp = mrb_intern_str(mrb, to_str(mrb, ss)); } + else { + mrb_value obj = mrb_funcall(mrb, ss, "inspect", 0); + mrb_raisef(mrb, E_TYPE_ERROR, "%s is not a symbol", + mrb_string_value_ptr(mrb, obj)); + } i++; } } @@ -1453,20 +1458,6 @@ mod_define_method(mrb_state *mrb, mrb_value self) return blk; } -static mrb_sym -mrb_sym_value(mrb_state *mrb, mrb_value val) -{ - if (mrb_string_p(val)) { - return mrb_intern_str(mrb, val); - } - else if(!mrb_symbol_p(val)) { - mrb_value obj = mrb_funcall(mrb, val, "inspect", 0); - mrb_raisef(mrb, E_TYPE_ERROR, "%s is not a symbol", - mrb_string_value_ptr(mrb, obj)); - } - return mrb_symbol(val); -} - static void check_cv_name(mrb_state *mrb, mrb_sym id) { @@ -1497,13 +1488,10 @@ check_cv_name(mrb_state *mrb, mrb_sym id) static mrb_value mrb_mod_cvar_defined(mrb_state *mrb, mrb_value mod) { - mrb_value sym; mrb_sym id; - mrb_get_args(mrb, "o", &sym); + mrb_get_args(mrb, "n", &id); - id = mrb_sym_value(mrb,sym); check_cv_name(mrb, id); - if(mrb_cv_defined(mrb, mod, id)) return mrb_true_value(); return mrb_false_value(); @@ -1527,11 +1515,9 @@ mrb_mod_cvar_defined(mrb_state *mrb, mrb_value mod) static mrb_value mrb_mod_cvar_get(mrb_state *mrb, mrb_value mod) { - mrb_value sym; mrb_sym id; - mrb_get_args(mrb, "o", &sym); - id = mrb_sym_value(mrb,sym); + mrb_get_args(mrb, "n", &id); check_cv_name(mrb, id); return mrb_cv_get(mrb, mod, id); } @@ -1557,12 +1543,10 @@ mrb_mod_cvar_get(mrb_state *mrb, mrb_value mod) static mrb_value mrb_mod_cvar_set(mrb_state *mrb, mrb_value mod) { - mrb_value sym, value; + mrb_value value; mrb_sym id; - mrb_get_args(mrb, "oo", &sym, &value); - - id = mrb_sym_value(mrb,sym); + mrb_get_args(mrb, "no", &id, &value); check_cv_name(mrb, id); mrb_cv_set(mrb, mod, id, value); return value; @@ -1594,16 +1578,13 @@ mrb_mod_cvar_set(mrb_state *mrb, mrb_value mod) mrb_value mrb_mod_remove_cvar(mrb_state *mrb, mrb_value mod) { - mrb_value sym, val; + mrb_value val; mrb_sym id; - mrb_get_args(mrb, "o", &sym); - - id = mrb_sym_value(mrb,sym); + mrb_get_args(mrb, "n", &id); check_cv_name(mrb, id); val = mrb_iv_remove(mrb, mod, id); - if (!mrb_undef_p(val)) return val; if (mrb_cv_defined(mrb, mod, id)){ @@ -1648,12 +1629,9 @@ mrb_mod_remove_cvar(mrb_state *mrb, mrb_value mod) static mrb_value mrb_mod_method_defined(mrb_state *mrb, mrb_value mod) { - mrb_value sym; mrb_sym id; - mrb_get_args(mrb, "o", &sym); - id = mrb_sym_value(mrb,sym); - + mrb_get_args(mrb, "n", &id); if (mrb_obj_respond_to(mrb_class_ptr(mod), id)) { return mrb_true_value(); } @@ -1717,11 +1695,11 @@ check_const_name(mrb_state *mrb, mrb_sym id) mrb_value mrb_mod_const_defined(mrb_state *mrb, mrb_value mod) { - mrb_value sym; - mrb_get_args(mrb, "o", &sym); + mrb_sym id; - check_const_name(mrb, mrb_sym_value(mrb,sym)); - if(mrb_const_defined(mrb, mod, mrb_sym_value(mrb, sym))) { + mrb_get_args(mrb, "n", &id); + check_const_name(mrb, id); + if(mrb_const_defined(mrb, mod, id)) { return mrb_true_value(); } return mrb_false_value(); @@ -1730,24 +1708,39 @@ mrb_mod_const_defined(mrb_state *mrb, mrb_value mod) mrb_value mrb_mod_const_get(mrb_state *mrb, mrb_value mod) { - mrb_value sym; - mrb_get_args(mrb, "o", &sym); + mrb_sym id; - check_const_name(mrb, mrb_sym_value(mrb,sym)); - return mrb_const_get(mrb, mod, mrb_sym_value(mrb, sym)); + mrb_get_args(mrb, "n", &id); + check_const_name(mrb, id); + return mrb_const_get(mrb, mod, id); } mrb_value mrb_mod_const_set(mrb_state *mrb, mrb_value mod) { - mrb_value sym, value; - mrb_get_args(mrb, "oo", &sym, &value); + mrb_sym id; + mrb_value value; - check_const_name(mrb, mrb_sym_value(mrb,sym)); - mrb_const_set(mrb, mod, mrb_sym_value(mrb, sym), value); + mrb_get_args(mrb, "no", &id, &value); + check_const_name(mrb, id); + mrb_const_set(mrb, mod, id, value); return value; } +mrb_value +mrb_mod_remove_const(mrb_state *mrb, mrb_value mod) +{ + mrb_sym id; + mrb_value val; + + mrb_get_args(mrb, "n", &id); + check_const_name(mrb, id); + val = mrb_iv_remove(mrb, mod, id); + if (mrb_undef_p(val)) { + mrb_name_error(mrb, id, "constant %s not defined", mrb_sym2name(mrb, id)); + } + return val; +} static mrb_value mrb_mod_eqq(mrb_state *mrb, mrb_value mod) @@ -1828,6 +1821,7 @@ mrb_init_class(mrb_state *mrb) mrb_define_method(mrb, mod, "const_defined?", mrb_mod_const_defined, ARGS_REQ(1)); /* 15.2.2.4.20 */ mrb_define_method(mrb, mod, "const_get", mrb_mod_const_get, ARGS_REQ(1)); /* 15.2.2.4.21 */ mrb_define_method(mrb, mod, "const_set", mrb_mod_const_set, ARGS_REQ(2)); /* 15.2.2.4.23 */ + mrb_define_method(mrb, mod, "remove_const", mrb_mod_remove_const, ARGS_REQ(1)); /* 15.2.2.4.40 */ mrb_define_method(mrb, mod, "define_method", mod_define_method, ARGS_REQ(1)); mrb_define_method(mrb, mod, "class_variables", mrb_mod_class_variables, ARGS_NONE()); /* 15.2.2.4.19 */ diff --git a/src/variable.c b/src/variable.c index 6661dae40..a2dca3cc6 100644 --- a/src/variable.c +++ b/src/variable.c @@ -885,7 +885,7 @@ mrb_const_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v) mrb_iv_set(mrb, mod, sym, v); } -void + void mrb_vm_const_set(mrb_state *mrb, mrb_sym sym, mrb_value v) { struct RClass *c = mrb->ci->proc->target_class; @@ -895,6 +895,13 @@ mrb_vm_const_set(mrb_state *mrb, mrb_sym sym, mrb_value v) } void +mrb_const_remove(mrb_state *mrb, mrb_value mod, mrb_sym sym) +{ + mod_const_check(mrb, mod); + mrb_iv_remove(mrb, mod, sym); +} + +void mrb_define_const(mrb_state *mrb, struct RClass *mod, const char *name, mrb_value v) { mrb_obj_iv_set(mrb, (struct RObject*)mod, mrb_intern(mrb, name), v); diff --git a/test/assert.rb b/test/assert.rb index 218a911d4..9f3231cd4 100644 --- a/test/assert.rb +++ b/test/assert.rb @@ -11,6 +11,11 @@ def assertion_string(err, str, iso=nil, e=nil) msg += " [#{iso}]" if iso && iso != '' msg += " => #{e.message}" if e msg += " (mrbgems: #{GEMNAME})" if Object.const_defined?(:GEMNAME) + if $mrbtest_assert && $mrbtest_assert.size > 0 + $mrbtest_assert.each do |idx, str, diff| + msg += "\n - Assertion[#{idx}] Failed: #{str}\n#{diff}" + end + end msg end @@ -25,8 +30,10 @@ end def assert(str = 'Assertion failed', iso = '') print(str, (iso != '' ? " [#{iso}]" : ''), ' : ') if $mrbtest_verbose begin - if(!yield) - $asserts.push(assertion_string('Fail: ', str, iso)) + $mrbtest_assert = [] + $mrbtest_assert_idx = 0 + if(!yield || $mrbtest_assert.size > 0) + $asserts.push(assertion_string('Fail: ', str, iso, nil)) $ko_test += 1 print('F') else @@ -37,10 +44,41 @@ def assert(str = 'Assertion failed', iso = '') $asserts.push(assertion_string('Error: ', str, iso, e)) $kill_test += 1 print('X') + ensure + $mrbtest_assert = nil end print("\n") if $mrbtest_verbose end +def assertion_diff(exp, act) + " Expected: #{exp.inspect}\n" + + " Actual: #{act.inspect}" +end + +def assert_true(ret, msg = nil, diff = nil) + if $mrbtest_assert + $mrbtest_assert_idx += 1 + if !ret + msg = "Expected #{ret.inspect} to be true" unless msg + diff = assertion_diff(true, ret) unless diff + $mrbtest_assert.push([$mrbtest_assert_idx, msg, diff]) + end + end + ret +end + +def assert_equal(exp, act, msg = nil) + msg = "Expected to be equal" unless msg + diff = assertion_diff(exp, act) + assert_true(exp == act, msg, diff) +end + +def assert_nil(obj, msg = nil) + msg = "Expected #{obj.inspect} to be nil" unless msg + diff = assertion_diff(nil, obj) + assert_true(obj.nil?, msg, diff) +end + ## # Report the test result and print all assertions # which were reported broken. diff --git a/test/t/module.rb b/test/t/module.rb index 286c2c085..6c1c1acda 100644 --- a/test/t/module.rb +++ b/test/t/module.rb @@ -241,6 +241,28 @@ assert('Module#remove_class_variable', '15.2.2.4.39') do not Test4RemoveClassVariable.class_variables.include? :@@cv end +assert('Module#remove_const', '15.2.2.4.40') do + module Test4RemoveConst + ExistingConst = 23 + end + + result = Test4RemoveConst.module_eval { remove_const :ExistingConst } + + name_error = false + begin + Test4RemoveConst.module_eval { remove_const :NonExistingConst } + rescue NameError + name_error = true + end + + # Constant removed from Module + not Test4RemoveConst.const_defined? :ExistingConst and + # Return value of binding + result == 23 and + # Name Error raised when Constant doesn't exist + name_error +end + assert('Module#remove_method', '15.2.2.4.41') do module Test4RemoveMethod class Parent diff --git a/test/t/string.rb b/test/t/string.rb index fac77075b..7d0b147d0 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -193,7 +193,9 @@ assert('String#eql?', '15.2.10.5.17') do end assert('String#gsub', '15.2.10.5.18') do - 'abcabc'.gsub('b', 'B') == 'aBcaBc' && 'abcabc'.gsub('b') { |w| w.capitalize } == 'aBcaBc' + 'abcabc'.gsub('b', 'B') == 'aBcaBc' and + 'abcabc'.gsub('b') { |w| w.capitalize } == 'aBcaBc' and + '#a#a#'.gsub('#', '$') == '$a$a$' end assert('String#gsub!', '15.2.10.5.19') do @@ -318,7 +320,9 @@ assert('String#split', '15.2.10.5.35') do end assert('String#sub', '15.2.10.5.36') do - 'abcabc'.sub('b', 'B') == 'aBcabc' && 'abcabc'.sub('b') { |w| w.capitalize } == 'aBcabc' + 'abcabc'.sub('b', 'B') == 'aBcabc' and + 'abcabc'.sub('b') { |w| w.capitalize } == 'aBcabc' and + 'aa#'.sub('#', '$') == 'aa$' end assert('String#sub!', '15.2.10.5.37') do diff --git a/tools/mirb/mirb.c b/tools/mirb/mirb.c index 85c3249d2..29685cf28 100644 --- a/tools/mirb/mirb.c +++ b/tools/mirb/mirb.c @@ -191,6 +191,10 @@ main(void) last_code_line[char_index] = '\0'; #else char* line = readline(code_block_open ? "* " : "> "); + if(line == NULL) { + printf("\n"); + break; + } strncat(last_code_line, line, sizeof(last_code_line)-1); add_history(line); free(line); |
