Changeset 439 for EcnlProtoTool/trunk/mruby-2.1.1/mrbgems
- Timestamp:
- Jul 9, 2020, 8:51:43 AM (4 years ago)
- Location:
- EcnlProtoTool/trunk/mruby-2.1.1
- Files:
-
- 111 added
- 5 deleted
- 95 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/default.gembox
r331 r439 1 1 MRuby::GemBox.new do |conf| 2 # Meta-programming features 3 conf.gem :core => "mruby-metaprog" 4 5 # Use standard IO/File class 6 conf.gem :core => "mruby-io" 7 8 # Use standard Array#pack, String#unpack methods 9 conf.gem :core => "mruby-pack" 10 2 11 # Use standard Kernel#sprintf method 3 12 conf.gem :core => "mruby-sprintf" … … 14 23 # Use standard Struct class 15 24 conf.gem :core => "mruby-struct" 25 26 # Use Comparable module extension 27 conf.gem :core => "mruby-compar-ext" 16 28 17 29 # Use Enumerable module extension … … 75 87 conf.gem :core => "mruby-class-ext" 76 88 89 # Use Method/UnboundMethod class 90 conf.gem :core => "mruby-method" 91 77 92 # Use mruby-compiler to build other mrbgems 78 93 conf.gem :core => "mruby-compiler" -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-array-ext/mrblib/array.rb
r331 r439 1 1 class Array 2 ##3 # call-seq:4 # Array.try_convert(obj) -> array or nil5 #6 # Tries to convert +obj+ into an array, using +to_ary+ method.7 # converted array or +nil+ if +obj+ cannot be converted for any reason.8 # This method can be used to check if an argument is an array.9 #10 # Array.try_convert([1]) #=> [1]11 # Array.try_convert("1") #=> nil12 #13 # if tmp = Array.try_convert(arg)14 # # the argument is an array15 # elsif tmp = String.try_convert(arg)16 # # the argument is a string17 # end18 #19 def self.try_convert(obj)20 if obj.respond_to?(:to_ary)21 obj.to_ary22 else23 nil24 end25 end26 27 2 ## 28 3 # call-seq: … … 42 17 # 43 18 def uniq!(&block) 44 ary = self.dup 45 result = [] 19 hash = {} 46 20 if block 21 self.each do |val| 22 key = block.call(val) 23 hash[key] = val unless hash.key?(key) 24 end 25 result = hash.values 26 else 47 27 hash = {} 48 while ary.size > 0 49 val = ary.shift 50 key = block.call(val) 51 hash[key] = val unless hash.has_key?(key) 52 end 53 hash.each_value do |value| 54 result << value 55 end 56 else 57 while ary.size > 0 58 result << ary.shift 59 ary.delete(result.last) 60 end 28 self.each do |val| 29 hash[val] = val 30 end 31 result = hash.keys 61 32 end 62 33 if result.size == self.size … … 82 53 def uniq(&block) 83 54 ary = self.dup 84 if block 85 ary.uniq!(&block) 86 else 87 ary.uniq! 88 end 55 ary.uniq!(&block) 89 56 ary 90 57 end … … 106 73 hash = {} 107 74 array = [] 108 elem.each { |x| hash[x] = true } 109 self.each { |x| array << x unless hash[x] } 75 idx = 0 76 len = elem.size 77 while idx < len 78 hash[elem[idx]] = true 79 idx += 1 80 end 81 idx = 0 82 len = size 83 while idx < len 84 v = self[idx] 85 array << v unless hash[v] 86 idx += 1 87 end 110 88 array 89 end 90 91 ## 92 # call-seq: 93 # ary.difference(other_ary1, other_ary2, ...) -> new_ary 94 # 95 # Returns a new array that is a copy of the original array, removing all 96 # occurrences of any item that also appear in +other_ary+. The order is 97 # preserved from the original array. 98 # 99 def difference(*args) 100 ary = self 101 args.each do |x| 102 ary = ary - x 103 end 104 ary 111 105 end 112 106 … … 130 124 ## 131 125 # call-seq: 126 # ary.union(other_ary,...) -> new_ary 127 # 128 # Set Union---Returns a new array by joining this array with 129 # <i>other_ary</i>, removing duplicates. 130 # 131 # ["a", "b", "c"].union(["c", "d", "a"], ["a", "c", "e"]) 132 # #=> ["a", "b", "c", "d", "e"] 133 # 134 def union(*args) 135 ary = self.dup 136 args.each do |x| 137 ary.concat(x) 138 ary.uniq! 139 end 140 ary 141 end 142 143 ## 144 # call-seq: 132 145 # ary & other_ary -> new_ary 133 146 # … … 142 155 hash = {} 143 156 array = [] 144 elem.each{|v| hash[v] = true } 145 self.each do |v| 157 idx = 0 158 len = elem.size 159 while idx < len 160 hash[elem[idx]] = true 161 idx += 1 162 end 163 idx = 0 164 len = size 165 while idx < len 166 v = self[idx] 146 167 if hash[v] 147 168 array << v 148 169 hash.delete v 149 170 end 171 idx += 1 150 172 end 151 173 array 174 end 175 176 ## 177 # call-seq: 178 # ary.intersection(other_ary,...) -> new_ary 179 # 180 # Set Intersection---Returns a new array containing elements common to 181 # this array and <i>other_ary</i>s, removing duplicates. The order is 182 # preserved from the original array. 183 # 184 # [1, 2, 3].intersection([3, 4, 1], [1, 3, 5]) #=> [1, 3] 185 # 186 def intersection(*args) 187 ary = self 188 args.each do |x| 189 ary = ary & x 190 end 191 ary 152 192 end 153 193 … … 170 210 # 171 211 def flatten(depth=nil) 172 ar = [] 173 self.each do |e| 174 if e.is_a?(Array) && (depth.nil? || depth > 0) 175 ar += e.flatten(depth.nil? ? nil : depth - 1) 176 else 177 ar << e 178 end 179 end 180 ar 212 res = dup 213 res.flatten! depth 214 res 181 215 end 182 216 … … 201 235 modified = false 202 236 ar = [] 203 self.each do |e| 237 idx = 0 238 len = size 239 while idx < len 240 e = self[idx] 204 241 if e.is_a?(Array) && (depth.nil? || depth > 0) 205 242 ar += e.flatten(depth.nil? ? nil : depth - 1) … … 208 245 ar << e 209 246 end 247 idx += 1 210 248 end 211 249 if modified … … 253 291 # for efficiency 254 292 def reverse_each(&block) 255 return to_enum :reverse_each unless block _given?293 return to_enum :reverse_each unless block 256 294 257 295 i = self.size - 1 … … 263 301 end 264 302 265 NONE=Object.new266 303 ## 267 304 # call-seq: … … 288 325 # 289 326 290 def fetch(n =nil, ifnone=NONE, &block)327 def fetch(n, ifnone=NONE, &block) 291 328 warn "block supersedes default value argument" if !n.nil? && ifnone != NONE && block 292 329 … … 475 512 476 513 def delete_if(&block) 477 return to_enum :delete_if unless block _given?514 return to_enum :delete_if unless block 478 515 479 516 idx = 0 … … 504 541 505 542 def reject!(&block) 506 return to_enum :reject! unless block _given?543 return to_enum :reject! unless block 507 544 508 545 len = self.size … … 594 631 595 632 def bsearch(&block) 596 return to_enum :bsearch unless block_given? 633 return to_enum :bsearch unless block 634 635 if idx = bsearch_index(&block) 636 self[idx] 637 else 638 nil 639 end 640 end 641 642 ## 643 # call-seq: 644 # ary.bsearch_index {|x| block } -> int or nil 645 # 646 # By using binary search, finds an index of a value from this array which 647 # meets the given condition in O(log n) where n is the size of the array. 648 # 649 # It supports two modes, depending on the nature of the block and they are 650 # exactly the same as in the case of #bsearch method with the only difference 651 # being that this method returns the index of the element instead of the 652 # element itself. For more details consult the documentation for #bsearch. 653 654 def bsearch_index(&block) 655 return to_enum :bsearch_index unless block 597 656 598 657 low = 0 599 high = s elf.size658 high = size 600 659 satisfied = false 660 601 661 while low < high 602 mid = low + ((high - low) / 2).truncate 603 val = self[mid] 604 v = block.call(val) 605 if v.is_a?(Integer) 606 return val if v == 0 607 smaller = v < 0 608 elsif v == true 662 mid = ((low+high)/2).truncate 663 res = block.call self[mid] 664 665 case res 666 when 0 # find-any mode: Found! 667 return mid 668 when Numeric # find-any mode: Continue... 669 in_lower_half = res < 0 670 when true # find-min mode 671 in_lower_half = true 609 672 satisfied = true 610 smaller = true 611 elsif v == false || v.nil? 612 smaller = false 613 end 614 if smaller 673 when false, nil # find-min mode 674 in_lower_half = false 675 else 676 raise TypeError, 'invalid block result (must be numeric, true, false or nil)' 677 end 678 679 if in_lower_half 615 680 high = mid 616 681 else … … 618 683 end 619 684 end 620 return nil if low == self.size 621 return nil unless satisfied 622 self[low] 623 end 624 625 ## 626 # call-seq: 627 # ary.delete_if { |item| block } -> ary 628 # ary.delete_if -> Enumerator 629 # 630 # Deletes every element of +self+ for which block evaluates to +true+. 631 # 632 # The array is changed instantly every time the block is called, not after 633 # the iteration is over. 634 # 635 # See also Array#reject! 636 # 637 # If no block is given, an Enumerator is returned instead. 638 # 639 # scores = [ 97, 42, 75 ] 640 # scores.delete_if {|score| score < 80 } #=> [97] 641 642 def delete_if(&block) 643 return to_enum :delete_if unless block_given? 644 645 idx = 0 646 while idx < self.size do 647 if block.call(self[idx]) 648 self.delete_at(idx) 649 else 650 idx += 1 651 end 652 end 653 self 685 686 satisfied ? low : nil 654 687 end 655 688 … … 670 703 671 704 def keep_if(&block) 672 return to_enum :keep_if unless block _given?705 return to_enum :keep_if unless block 673 706 674 707 idx = 0 … … 699 732 700 733 def select!(&block) 701 return to_enum :select! unless block _given?734 return to_enum :select! unless block 702 735 703 736 result = [] 704 self.each do |x| 705 result << x if block.call(x) 706 end 707 return nil if self.size == result.size 737 idx = 0 738 len = size 739 while idx < len 740 elem = self[idx] 741 result << elem if block.call(elem) 742 idx += 1 743 end 744 return nil if len == result.size 708 745 self.replace(result) 709 746 end … … 727 764 if block 728 765 idx = 0 729 self.each do |*e| 730 return idx if block.call(*e) 766 len = size 767 while idx < len 768 return idx if block.call self[idx] 731 769 idx += 1 732 770 end … … 735 773 end 736 774 nil 737 end738 739 ##740 # call-seq:741 # ary.to_ary -> ary742 #743 # Returns +self+.744 #745 def to_ary746 self747 775 end 748 776 … … 763 791 end 764 792 end 793 794 ## 795 # call-seq: 796 # ary.permutation { |p| block } -> ary 797 # ary.permutation -> Enumerator 798 # ary.permutation(n) { |p| block } -> ary 799 # ary.permutation(n) -> Enumerator 800 # 801 # When invoked with a block, yield all permutations of length +n+ of the 802 # elements of the array, then return the array itself. 803 # 804 # If +n+ is not specified, yield all permutations of all elements. 805 # 806 # The implementation makes no guarantees about the order in which the 807 # permutations are yielded. 808 # 809 # If no block is given, an Enumerator is returned instead. 810 # 811 # Examples: 812 # 813 # a = [1, 2, 3] 814 # a.permutation.to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 815 # a.permutation(1).to_a #=> [[1],[2],[3]] 816 # a.permutation(2).to_a #=> [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]] 817 # a.permutation(3).to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 818 # a.permutation(0).to_a #=> [[]] # one permutation of length 0 819 # a.permutation(4).to_a #=> [] # no permutations of length 4 820 def permutation(n=self.size, &block) 821 return to_enum(:permutation, n) unless block 822 size = self.size 823 if n == 0 824 yield [] 825 elsif 0 < n && n <= size 826 i = 0 827 while i<size 828 result = [self[i]] 829 if n-1 > 0 830 ary = self[0...i] + self[i+1..-1] 831 ary.permutation(n-1) do |c| 832 yield result + c 833 end 834 else 835 yield result 836 end 837 i += 1 838 end 839 end 840 self 841 end 842 843 ## 844 # call-seq: 845 # ary.combination(n) { |c| block } -> ary 846 # ary.combination(n) -> Enumerator 847 # 848 # When invoked with a block, yields all combinations of length +n+ of elements 849 # from the array and then returns the array itself. 850 # 851 # The implementation makes no guarantees about the order in which the 852 # combinations are yielded. 853 # 854 # If no block is given, an Enumerator is returned instead. 855 # 856 # Examples: 857 # 858 # a = [1, 2, 3, 4] 859 # a.combination(1).to_a #=> [[1],[2],[3],[4]] 860 # a.combination(2).to_a #=> [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]] 861 # a.combination(3).to_a #=> [[1,2,3],[1,2,4],[1,3,4],[2,3,4]] 862 # a.combination(4).to_a #=> [[1,2,3,4]] 863 # a.combination(0).to_a #=> [[]] # one combination of length 0 864 # a.combination(5).to_a #=> [] # no combinations of length 5 865 866 def combination(n, &block) 867 return to_enum(:combination, n) unless block 868 size = self.size 869 if n == 0 870 yield [] 871 elsif n == 1 872 i = 0 873 while i<size 874 yield [self[i]] 875 i += 1 876 end 877 elsif n <= size 878 i = 0 879 while i<size 880 result = [self[i]] 881 self[i+1..-1].combination(n-1) do |c| 882 yield result + c 883 end 884 i += 1 885 end 886 end 887 self 888 end 889 890 ## 891 # call-seq: 892 # ary.transpose -> new_ary 893 # 894 # Assumes that self is an array of arrays and transposes the rows and columns. 895 # 896 # If the length of the subarrays don't match, an IndexError is raised. 897 # 898 # Examples: 899 # 900 # a = [[1,2], [3,4], [5,6]] 901 # a.transpose #=> [[1, 3, 5], [2, 4, 6]] 902 903 def transpose 904 return [] if empty? 905 906 column_count = nil 907 self.each do |row| 908 raise TypeError unless row.is_a?(Array) 909 column_count ||= row.size 910 raise IndexError, 'element size differs' unless column_count == row.size 911 end 912 913 Array.new(column_count) do |column_index| 914 self.map { |row| row[column_index] } 915 end 916 end 917 918 ## 919 # call-seq: 920 # ary.to_h -> Hash 921 # ary.to_h{|item| ... } -> Hash 922 # 923 # Returns the result of interpreting <i>aray</i> as an array of 924 # <tt>[key, value]</tt> pairs. If a block is given, it should 925 # return <tt>[key, value]</tt> pairs to construct a hash. 926 # 927 # [[:foo, :bar], [1, 2]].to_h 928 # # => {:foo => :bar, 1 => 2} 929 # [1, 2].to_h{|x| [x, x*2]} 930 # # => {1 => 2, 2 => 4} 931 # 932 def to_h(&blk) 933 h = {} 934 self.each do |v| 935 v = blk.call(v) if blk 936 raise TypeError, "wrong element type #{v.class}" unless Array === v 937 raise ArgumentError, "wrong array length (expected 2, was #{v.length})" unless v.length == 2 938 h[v[0]] = v[1] 939 end 940 h 941 end 942 943 alias append push 944 alias prepend unshift 945 alias filter! select! 765 946 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-array-ext/src/array.c
r331 r439 66 66 for (i = 0; i < RARRAY_LEN(ary); ++i) { 67 67 v = RARRAY_PTR(ary)[i]; 68 if (mrb_ type(v) == MRB_TT_ARRAY&&68 if (mrb_array_p(v) && 69 69 RARRAY_LEN(v) > 1 && 70 70 mrb_equal(mrb, RARRAY_PTR(v)[1], value)) … … 107 107 } 108 108 109 /*110 * call-seq:111 * ary.to_h -> Hash112 *113 * Returns the result of interpreting <i>aray</i> as an array of114 * <tt>[key, value]</tt> paris.115 *116 * [[:foo, :bar], [1, 2]].to_h117 * # => {:foo => :bar, 1 => 2}118 *119 */120 121 static mrb_value122 mrb_ary_to_h(mrb_state *mrb, mrb_value ary)123 {124 mrb_int i;125 mrb_value v, hash;126 127 hash = mrb_hash_new_capa(mrb, 0);128 129 for (i = 0; i < RARRAY_LEN(ary); ++i) {130 v = mrb_check_array_type(mrb, RARRAY_PTR(ary)[i]);131 132 if (mrb_nil_p(v)) {133 mrb_raisef(mrb, E_TYPE_ERROR, "wrong element type %S at %S (expected array)",134 mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, ary_elt(ary, i))),135 mrb_fixnum_value(i)136 );137 }138 139 if (RARRAY_LEN(v) != 2) {140 mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong array length at %S (expected 2, was %S)",141 mrb_fixnum_value(i),142 mrb_fixnum_value(RARRAY_LEN(v))143 );144 }145 146 mrb_hash_set(mrb, hash, RARRAY_PTR(v)[0], RARRAY_PTR(v)[1]);147 }148 149 return hash;150 }151 109 152 110 /* … … 175 133 { 176 134 struct RArray *a = mrb_ary_ptr(self); 177 mrb_int i, j, k, len; 178 mrb_value index; 135 mrb_int i, j, k, len, alen; 179 136 mrb_value val; 180 137 mrb_value *ptr; … … 183 140 mrb_ary_modify(mrb, a); 184 141 185 if (mrb_get_args(mrb, "o|i", &index, &len) == 1) { 142 if (mrb_get_argc(mrb) == 1) { 143 mrb_value index; 144 145 mrb_get_args(mrb, "o|i", &index, &len); 186 146 switch (mrb_type(index)) { 187 147 case MRB_TT_RANGE: 188 if (mrb_range_beg_len(mrb, index, &i, &len, a->len, TRUE) == 1) {148 if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == MRB_RANGE_OK) { 189 149 goto delete_pos_len; 190 150 } … … 201 161 } 202 162 203 i = mrb_fixnum(index);163 mrb_get_args(mrb, "ii", &i, &len); 204 164 delete_pos_len: 205 if (i < 0) i += a->len; 206 if (i < 0 || a->len < i) return mrb_nil_value(); 165 alen = ARY_LEN(a); 166 if (i < 0) i += alen; 167 if (i < 0 || alen < i) return mrb_nil_value(); 207 168 if (len < 0) return mrb_nil_value(); 208 if (a ->len == i) return mrb_ary_new(mrb);209 if (len > a ->len - i) len = a->len - i;169 if (alen == i) return mrb_ary_new(mrb); 170 if (len > alen - i) len = alen - i; 210 171 211 172 ary = mrb_ary_new_capa(mrb, len); 212 173 ptr = ARY_PTR(a); 213 174 for (j = i, k = 0; k < len; ++j, ++k) { 214 mrb_ary_push(mrb, ary, a->ptr[j]);215 } 216 217 ptr = a->ptr +i;218 for (j = i; j < a ->len - len; ++j) {175 mrb_ary_push(mrb, ary, ptr[j]); 176 } 177 178 ptr += i; 179 for (j = i; j < alen - len; ++j) { 219 180 *ptr = *(ptr+len); 220 181 ++ptr; 221 182 } 222 183 223 mrb_ary_resize(mrb, self, a ->len - len);184 mrb_ary_resize(mrb, self, alen - len); 224 185 return ary; 225 186 } … … 234 195 mrb_define_method(mrb, a, "rassoc", mrb_ary_rassoc, MRB_ARGS_REQ(1)); 235 196 mrb_define_method(mrb, a, "values_at", mrb_ary_values_at, MRB_ARGS_ANY()); 236 mrb_define_method(mrb, a, "to_h", mrb_ary_to_h, MRB_ARGS_REQ(0)); 237 mrb_define_method(mrb, a, "slice!", mrb_ary_slice_bang, MRB_ARGS_ANY()); 197 mrb_define_method(mrb, a, "slice!", mrb_ary_slice_bang, MRB_ARGS_ARG(1,1)); 238 198 } 239 199 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-array-ext/test/array.rb
r331 r439 2 2 # Array(Ext) Test 3 3 4 assert("Array.try_convert") do 5 assert_nil Array.try_convert(0) 6 assert_nil Array.try_convert(nil) 7 assert_equal [], Array.try_convert([]) 8 assert_equal [1,2,3], Array.try_convert([1,2,3]) 4 def assert_permutation_combination(exp, receiver, meth, *args) 5 act = [] 6 ret = receiver.__send__(meth, *args) { |v| act << v } 7 assert "assert_#{meth}" do 8 assert_equal(exp, act.sort) 9 assert_same(receiver, ret) 10 end 11 end 12 13 def assert_permutation(exp, receiver, *args) 14 assert_permutation_combination(exp, receiver, :permutation, *args) 15 end 16 17 def assert_combination(exp, receiver, *args) 18 assert_permutation_combination(exp, receiver, :combination, *args) 9 19 end 10 20 … … 76 86 end 77 87 88 assert("Array#union") do 89 a = [1, 2, 3, 1] 90 b = [1, 4] 91 c = [1, 5] 92 93 assert_equal [1, 2, 3, 4, 5], a.union(b,c) 94 end 95 96 assert("Array#difference") do 97 a = [1, 2, 3, 1, 6, 7] 98 b = [1, 4, 6] 99 c = [1, 5, 7] 100 101 assert_equal [2, 3], a.difference(b,c) 102 end 103 78 104 assert("Array#&") do 79 105 a = [1, 2, 3, 1] … … 84 110 assert_equal [1], (a & b) 85 111 assert_equal [1, 2, 3, 1], a 112 end 113 114 assert("Array#intersection") do 115 a = [1, 2, 3, 1, 8, 6, 7, 8] 116 b = [1, 4, 6, 8] 117 c = [1, 5, 7, 8] 118 119 assert_equal [1, 8], a.intersection(b,c) 86 120 end 87 121 … … 162 196 end 163 197 assert_equal [ "d", "c", "b", "a" ], b 164 165 if Object.const_defined?(:Enumerator)166 assert_equal [ "d", "c", "b", "a" ], a.reverse_each.to_a167 else168 true169 end170 198 end 171 199 … … 229 257 assert("Array#bsearch") do 230 258 # Find minimum mode 231 a = [0, 4, 7, 10, 12] 232 assert_include [4, 7], a.bsearch {|x| x >= 4 } 233 assert_equal 7, a.bsearch {|x| x >= 6 } 234 assert_equal 0, a.bsearch {|x| x >= -1 } 235 assert_nil a.bsearch {|x| x >= 100 } 259 a = [0, 2, 4] 260 assert_equal 0, a.bsearch{ |x| x >= -1 } 261 assert_equal 0, a.bsearch{ |x| x >= 0 } 262 assert_equal 2, a.bsearch{ |x| x >= 1 } 263 assert_equal 2, a.bsearch{ |x| x >= 2 } 264 assert_equal 4, a.bsearch{ |x| x >= 3 } 265 assert_equal 4, a.bsearch{ |x| x >= 4 } 266 assert_nil a.bsearch{ |x| x >= 5 } 236 267 237 268 # Find any mode 238 a = [0, 4, 7, 10, 12] 239 assert_include [4, 7], a.bsearch {|x| 1 - (x / 4).truncate } 240 assert_nil a.bsearch {|x| 4 - (x / 2).truncate } 241 assert_equal(nil, a.bsearch {|x| 1 }) 242 assert_equal(nil, a.bsearch {|x| -1 }) 243 end 244 245 assert("Array#delete_if") do 246 a = [1, 2, 3, 4, 5] 247 assert_equal [1, 2, 3, 4, 5], a.delete_if { false } 248 assert_equal [1, 2, 3, 4, 5], a 249 250 a = [1, 2, 3, 4, 5] 251 assert_equal [], a.delete_if { true } 252 assert_equal [], a 253 254 a = [ 1, 2, 3, 4, 5 ] 255 assert_equal [1, 2, 3], a.delete_if { |val| val > 3 } 256 end 269 a = [0, 4, 8] 270 def between(lo, x, hi) 271 if x < lo 272 1 273 elsif x > hi 274 -1 275 else 276 0 277 end 278 end 279 assert_nil a.bsearch{ |x| between(-3, x, -1) } 280 assert_equal 0, a.bsearch{ |x| between(-1, x, 1) } 281 assert_nil a.bsearch{ |x| between( 1, x, 3) } 282 assert_equal 4, a.bsearch{ |x| between( 3, x, 5) } 283 assert_nil a.bsearch{ |x| between( 5, x, 7) } 284 assert_equal 8, a.bsearch{ |x| between( 7, x, 9) } 285 assert_nil a.bsearch{ |x| between( 9, x, 11) } 286 287 assert_equal 0, a.bsearch{ |x| between( 0, x, 3) } 288 assert_equal 4, a.bsearch{ |x| between( 0, x, 4) } 289 assert_equal 4, a.bsearch{ |x| between( 4, x, 8) } 290 assert_equal 8, a.bsearch{ |x| between( 5, x, 8) } 291 292 # Invalid block result 293 assert_raise TypeError, 'invalid block result (must be numeric, true, false or nil)' do 294 a.bsearch{ 'I like to watch the world burn' } 295 end 296 end 297 298 # tested through Array#bsearch 299 #assert("Array#bsearch_index") do 300 #end 257 301 258 302 assert("Array#keep_if") do … … 302 346 end 303 347 304 assert('Array#to_h (Modified)') do305 class A306 def to_ary307 $a.clear308 nil309 end310 end311 $a = [A.new]312 assert_raise(TypeError) { $a.to_h }313 end314 315 348 assert("Array#index (block)") do 316 349 assert_nil (1..10).to_a.index { |i| i % 5 == 0 and i % 7 == 0 } 317 350 assert_equal 34, (1..100).to_a.index { |i| i % 5 == 0 and i % 7 == 0 } 318 end319 320 assert("Array#to_ary") do321 assert_equal [], [].to_ary322 assert_equal [1,2,3], [1,2,3].to_ary323 351 end 324 352 … … 353 381 assert_equal(j, nil) 354 382 end 383 384 assert("Array#permutation") do 385 a = [1, 2, 3] 386 assert_permutation([[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]], a) 387 assert_permutation([[1],[2],[3]], a, 1) 388 assert_permutation([[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]], a, 2) 389 assert_permutation([[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]], a, 3) 390 assert_permutation([[]], a, 0) 391 assert_permutation([], a, 4) 392 assert_permutation([], a, -1) 393 end 394 395 assert("Array#combination") do 396 a = [1, 2, 3, 4] 397 assert_combination([[1],[2],[3],[4]], a, 1) 398 assert_combination([[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]], a, 2) 399 assert_combination([[1,2,3],[1,2,4],[1,3,4],[2,3,4]], a, 3) 400 assert_combination([[1,2,3,4]], a, 4) 401 assert_combination([[]], a, 0) 402 assert_combination([], a, 5) 403 assert_combination([], a, -1) 404 end 405 406 assert('Array#transpose') do 407 assert_equal([].transpose, []) 408 assert_equal([[]].transpose, []) 409 assert_equal([[1]].transpose, [[1]]) 410 assert_equal([[1,2,3]].transpose, [[1], [2], [3]]) 411 assert_equal([[1], [2], [3]].transpose, [[1,2,3]]) 412 assert_equal([[1,2], [3,4], [5,6]].transpose, [[1,3,5], [2,4,6]]) 413 assert_raise(TypeError) { [1].transpose } 414 assert_raise(IndexError) { [[1], [2,3,4]].transpose } 415 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/bintest/print.rb
r331 r439 1 1 require 'open3' 2 2 require 'tempfile' 3 require 'strscan' 3 4 4 5 class BinTest_MrubyBinDebugger 5 @debug1=false6 @debug2=true6 # @debug1=false 7 # @debug2=true 7 8 def self.test(rubysource, testcase) 8 9 script, bin = Tempfile.new(['test', '.rb']), Tempfile.new(['test', '.mrb']) … … 20 21 stdin_data = testcase.map{|t| t[:cmd]}.join("\n") << "\n" 21 22 23 prompt = /^\(#{Regexp.escape(script.path)}:\d+\) / 22 24 ["bin/mrdb #{script.path}","bin/mrdb -b #{bin.path}"].each do |cmd| 23 25 o, s = Open3.capture2(cmd, :stdin_data => stdin_data) 24 25 exp_vals = testcase.map{|t| t.fetch(:exp, nil)} 26 scanner = StringScanner.new(o) 27 scanner.skip_until(prompt) 28 testcase.each do |tc| 29 exp = tc[:exp] 30 if exp 31 act = scanner.scan_until(/\n/) 32 break unless assert_operator act, :start_with?, exp 33 end 34 scanner.skip_until(prompt) 35 end 36 26 37 =begin 27 38 if @debug1 … … 42 53 end 43 54 =end 44 idx = 045 exp_vals.each do |exp|46 next if exp.nil?47 idx = o.index(exp, idx)48 assert_false idx.nil?49 break unless idx50 idx += 151 end52 55 end 53 56 end … … 91 94 # test case 92 95 tc = [] 93 tc << {:cmd=>"p (1+2", :exp=>'$1 = SyntaxError'}94 tc << {:cmd=>"p bar", :exp=>'$2 = NoMethodError'}96 tc << {:cmd=>"p (1+2", :exp=>'$1 = line 1: syntax error'} 97 tc << {:cmd=>"p bar", :exp=>'$2 = undefined method'} 95 98 96 99 BinTest_MrubyBinDebugger.test(src, tc) … … 318 321 SRC 319 322 320 # todo: wait for 'break' to be impl imented323 # todo: wait for 'break' to be implemented 321 324 tc = [] 322 325 9.times { tc << {:cmd=>"s"} } … … 342 345 tc << {:cmd=>"p 0x100", :exp=>'$4 = 256'} 343 346 tc << {:cmd=>"p 1_234", :exp=>'$5 = 1234'} 344 tc << {:cmd=>"p 0b1000_0000", :exp=>"$6 = #{0b1000_0000 .to_s}"}345 tc << {:cmd=>"p 0x1000_0000", :exp=>"$7 = #{0x1000_0000 .to_s}"}347 tc << {:cmd=>"p 0b1000_0000", :exp=>"$6 = #{0b1000_0000}"} 348 tc << {:cmd=>"p 0x1000_0000", :exp=>"$7 = #{0x1000_0000}"} 346 349 347 350 tc << {:cmd=>"p 3.14", :exp=>'$8 = 3.14'} 348 351 tc << {:cmd=>"p -12.3", :exp=>'$9 = -12.3'} 349 tc << {:cmd=>"p +12.000", :exp=>'$10 = 12 .0'}350 tc << {:cmd=>"p 1e4", :exp=>'$11 = 10000 .0'}352 tc << {:cmd=>"p +12.000", :exp=>'$10 = 12'} 353 tc << {:cmd=>"p 1e4", :exp=>'$11 = 10000'} 351 354 tc << {:cmd=>"p -0.1e-2", :exp=>'$12 = -0.001'} 352 355 … … 369 372 tc << {:cmd=>'p "str"', :exp=>'$1 = "str"'} 370 373 tc << {:cmd=>'p "s\tt\rr\n"', :exp=>'$2 = "s\\tt\\rr\\n"'} 371 tc << {:cmd=>'p "\C-a\C-z"', :exp=>'$3 = "\\ 001\\032"'}374 tc << {:cmd=>'p "\C-a\C-z"', :exp=>'$3 = "\\x01\\x1a"'} 372 375 tc << {:cmd=>'p "#{foo+bar}"', :exp=>'$4 = "foobar"'} 373 376 … … 375 378 tc << {:cmd=>'p \'s\\tt\\rr\\n\'', :exp=>'$6 = "s\\\\tt\\\\rr\\\\n"'} 376 379 tc << {:cmd=>'p \'\\C-a\\C-z\'', :exp=>'$7 = "\\\\C-a\\\\C-z"'} 377 tc << {:cmd=>'p \'#{foo+bar}\'', :exp=>'$8 = " #{foo+bar}"'}380 tc << {:cmd=>'p \'#{foo+bar}\'', :exp=>'$8 = "\\#{foo+bar}"'} 378 381 379 382 tc << {:cmd=>'p %!str!', :exp=>'$9 = "str"'} 380 383 tc << {:cmd=>'p %!s\tt\rr\n!', :exp=>'$10 = "s\\tt\\rr\\n"'} 381 tc << {:cmd=>'p %!\C-a\C-z!', :exp=>'$11 = "\\ 001\\032"'}384 tc << {:cmd=>'p %!\C-a\C-z!', :exp=>'$11 = "\\x01\\x1a"'} 382 385 tc << {:cmd=>'p %!#{foo+bar}!', :exp=>'$12 = "foobar"'} 383 386 384 387 tc << {:cmd=>'p %Q!str!', :exp=>'$13 = "str"'} 385 388 tc << {:cmd=>'p %Q!s\tt\rr\n!', :exp=>'$14 = "s\\tt\\rr\\n"'} 386 tc << {:cmd=>'p %Q!\C-a\C-z!', :exp=>'$15 = "\\ 001\\032"'}389 tc << {:cmd=>'p %Q!\C-a\C-z!', :exp=>'$15 = "\\x01\\x1a"'} 387 390 tc << {:cmd=>'p %Q!#{foo+bar}!', :exp=>'$16 = "foobar"'} 388 391 … … 390 393 tc << {:cmd=>'p %q!s\\tt\\rr\\n!', :exp=>'$18 = "s\\\\tt\\\\rr\\\\n"'} 391 394 tc << {:cmd=>'p %q!\\C-a\\C-z!', :exp=>'$19 = "\\\\C-a\\\\C-z"'} 392 tc << {:cmd=>'p %q!#{foo+bar}!', :exp=>'$20 = " #{foo+bar}"'}395 tc << {:cmd=>'p %q!#{foo+bar}!', :exp=>'$20 = "\\#{foo+bar}"'} 393 396 394 397 BinTest_MrubyBinDebugger.test(src, tc) … … 411 414 tc << {:cmd=>'p [ 5, 12, 8, 10, ]', :exp=>'$2 = [5, 12, 8, 10]'} 412 415 tc << {:cmd=>'p [1,2.5,"#{foo+bar}"]', :exp=>'$3 = [1, 2.5, "foobar"]'} 413 tc << {:cmd=>'p %w[3.14 A\ &\ B #{foo}]', :exp=>'$4 = ["3.14", "A & B", " #{foo}"]'}416 tc << {:cmd=>'p %w[3.14 A\ &\ B #{foo}]', :exp=>'$4 = ["3.14", "A & B", "\#{foo}"]'} 414 417 tc << {:cmd=>'p %W[3.14 A\ &\ B #{foo}]', :exp=>'$5 = ["3.14", "A & B", "foo"]'} 415 418 … … 589 592 590 593 tc << {:cmd=>'p undefined=-1', :exp=>'$3 = -1'} 591 tc << {:cmd=>'p "#{undefined}"', :exp=>'$4 = NoMethodError'}594 tc << {:cmd=>'p "#{undefined}"', :exp=>'$4 = undefined method'} 592 595 593 596 BinTest_MrubyBinDebugger.test(src, tc) … … 627 630 628 631 tc << {:cmd=>'p undefined=-1', :exp=>'$14 = -1'} 629 tc << {:cmd=>'p "#{undefined}"', :exp=>'$15 = NoMethodError'}632 tc << {:cmd=>'p "#{undefined}"', :exp=>'$15 = undefined method'} 630 633 631 634 BinTest_MrubyBinDebugger.test(src, tc) … … 695 698 696 699 tc << {:cmd=>'p undefined=-1', :exp=>'$14 = -1'} 697 tc << {:cmd=>'p "#{undefined}"', :exp=>'$15 = NoMethodError'} 698 699 BinTest_MrubyBinDebugger.test(src, tc) 700 end 701 700 tc << {:cmd=>'p "#{undefined}"', :exp=>'$15 = undefined method'} 701 702 BinTest_MrubyBinDebugger.test(src, tc) 703 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c
r331 r439 85 85 86 86 static uint16_t 87 check_file_lineno( struct mrb_irep *irep, const char *file, uint16_t lineno)87 check_file_lineno(mrb_state *mrb, struct mrb_irep *irep, const char *file, uint16_t lineno) 88 88 { 89 89 mrb_irep_debug_info_file *info_file; … … 94 94 95 95 for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { 96 const char *filename; 96 97 info_file = irep->debug_info->files[f_idx]; 97 if (!strcmp(info_file->filename, file)) { 98 filename = mrb_sym_name_len(mrb, info_file->filename_sym, NULL); 99 if (!strcmp(filename, file)) { 98 100 result = MRB_DEBUG_BP_FILE_OK; 99 101 … … 104 106 } 105 107 for (i=0; i < irep->rlen; ++i) { 106 result |= check_file_lineno( irep->reps[i], file, lineno);108 result |= check_file_lineno(mrb, irep->reps[i], file, lineno); 107 109 if (result == (MRB_DEBUG_BP_FILE_OK | MRB_DEBUG_BP_LINENO_OK)) { 108 110 return result; … … 113 115 } 114 116 115 static const char*116 get_class_name(mrb_state *mrb, struct RClass *class_obj)117 {118 struct RClass *outer;119 mrb_sym class_sym;120 121 outer = mrb_class_outer_module(mrb, class_obj);122 class_sym = mrb_class_sym(mrb, class_obj, outer);123 return mrb_sym2name(mrb, class_sym);124 }125 126 117 static int32_t 127 118 compare_break_method(mrb_state *mrb, mrb_debug_breakpoint *bp, struct RClass *class_obj, mrb_sym method_sym, mrb_bool* isCfunc) … … 129 120 const char* class_name; 130 121 const char* method_name; 131 struct RProc*m;122 mrb_method_t m; 132 123 struct RClass* sc; 133 124 const char* sn; … … 136 127 mrb_bool is_defined; 137 128 138 method_name = mrb_sym 2name(mrb, method_sym);129 method_name = mrb_sym_name(mrb, method_sym); 139 130 140 131 method_p = &bp->point.methodpoint; 141 132 if (strcmp(method_p->method_name, method_name) == 0) { 142 class_name = get_class_name(mrb, class_obj);133 class_name = mrb_class_name(mrb, class_obj); 143 134 if (class_name == NULL) { 144 135 if (method_p->class_name == NULL) { … … 148 139 else if (method_p->class_name != NULL) { 149 140 m = mrb_method_search_vm(mrb, &class_obj, method_sym); 150 if ( m == NULL) {141 if (MRB_METHOD_UNDEF_P(m)) { 151 142 return MRB_DEBUG_OK; 152 143 } 153 if (MRB_ PROC_CFUNC_P(m)) {144 if (MRB_METHOD_CFUNC_P(m)) { 154 145 *isCfunc = TRUE; 155 146 } … … 163 154 ssym = mrb_symbol(mrb_check_intern_cstr(mrb, method_p->method_name)); 164 155 m = mrb_method_search_vm(mrb, &sc, ssym); 165 if ( m == NULL) {156 if (MRB_METHOD_UNDEF_P(m)) { 166 157 return MRB_DEBUG_OK; 167 158 } 168 159 169 class_name = get_class_name(mrb, class_obj);170 sn = get_class_name(mrb, sc);160 class_name = mrb_class_name(mrb, class_obj); 161 sn = mrb_class_name(mrb, sc); 171 162 if (strcmp(sn, class_name) == 0) { 172 163 return bp->bpno; … … 197 188 198 189 /* file and lineno check (line type mrb_debug_line_ary only.) */ 199 result = check_file_lineno( dbg->root_irep, file, lineno);190 result = check_file_lineno(mrb, dbg->root_irep, file, lineno); 200 191 if (result == 0) { 201 192 return MRB_DEBUG_BREAK_INVALID_FILE; … … 205 196 } 206 197 207 set_file = mrb_malloc(mrb, strlen(file) + 1);198 set_file = (char*)mrb_malloc(mrb, strlen(file) + 1); 208 199 209 200 index = dbg->bpnum; … … 242 233 243 234 if (class_name != NULL) { 244 set_class = mrb_malloc(mrb, strlen(class_name) + 1);235 set_class = (char*)mrb_malloc(mrb, strlen(class_name) + 1); 245 236 strncpy(set_class, class_name, strlen(class_name) + 1); 246 237 } … … 249 240 } 250 241 251 set_method = mrb_malloc(mrb, strlen(method_name) + 1);242 set_method = (char*)mrb_malloc(mrb, strlen(method_name) + 1); 252 243 253 244 strncpy(set_method, method_name, strlen(method_name) + 1); … … 438 429 439 430 static mrb_bool 440 check_start_pc_for_line(mrb_ irep *irep,mrb_code *pc, uint16_t line)431 check_start_pc_for_line(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, uint16_t line) 441 432 { 442 433 if (pc > irep->iseq) { 443 if (line == mrb_debug_get_line( irep, (uint32_t)(pc - irep->iseq - 1))) {434 if (line == mrb_debug_get_line(mrb, irep, pc - irep->iseq - 1)) { 444 435 return FALSE; 445 436 } … … 459 450 } 460 451 461 if (!check_start_pc_for_line( dbg->irep, dbg->pc, line)) {452 if (!check_start_pc_for_line(mrb, dbg->irep, dbg->pc, line)) { 462 453 return MRB_DEBUG_OK; 463 454 } … … 515 506 return 0; 516 507 } 517 518 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c
r331 r439 49 49 } 50 50 51 path = mrb_malloc(mrb, len);51 path = (char*)mrb_malloc(mrb, len); 52 52 memset(path, 0, len); 53 53 … … 65 65 { 66 66 size_t len; 67 char *p, *dir; 67 const char *p; 68 char *dir; 68 69 69 70 if (path == NULL) { … … 74 75 len = p != NULL ? (size_t)(p - path) : strlen(path); 75 76 76 dir = mrb_malloc(mrb, len + 1);77 dir = (char*)mrb_malloc(mrb, len + 1); 77 78 strncpy(dir, path, len); 78 79 dir[len] = '\0'; … … 84 85 source_file_new(mrb_state *mrb, mrb_debug_context *dbg, char *filename) 85 86 { 86 source_file *file = NULL;87 88 file = mrb_malloc(mrb, sizeof(source_file));87 source_file *file; 88 89 file = (source_file*)mrb_malloc(mrb, sizeof(source_file)); 89 90 90 91 memset(file, '\0', sizeof(source_file)); … … 97 98 98 99 file->lineno = 1; 99 file->path = mrb_malloc(mrb, strlen(filename) + 1);100 file->path = (char*)mrb_malloc(mrb, strlen(filename) + 1); 100 101 strcpy(file->path, filename); 101 102 return file; … … 175 176 const char *search_path[3]; 176 177 char *path = NULL; 178 const char *srcname = strrchr(filename, '/'); 179 180 if (srcname) srcname++; 181 else srcname = filename; 177 182 178 183 search_path[0] = srcpath; 179 search_path[1] = dirname(mrb, mrb_debug_get_filename(mr db->dbg->root_irep, 0));184 search_path[1] = dirname(mrb, mrb_debug_get_filename(mrb, mrdb->dbg->irep, 0)); 180 185 search_path[2] = "."; 181 186 … … 185 190 } 186 191 187 if ((path = build_path(mrb, search_path[i], filename)) == NULL) {192 if ((path = build_path(mrb, search_path[i], srcname)) == NULL) { 188 193 continue; 189 194 } -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c
r331 r439 22 22 c->no_exec = TRUE; 23 23 c->capture_errors = TRUE; 24 c->filename = (char*)dbg->prvfile;24 mrbc_filename(mrb, c, (const char*)dbg->prvfile); 25 25 c->lineno = dbg->prvline; 26 26 … … 32 32 33 33 mrb_value 34 mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t len, mrb_bool *exc )34 mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t len, mrb_bool *exc, int direct_eval) 35 35 { 36 void (*tmp)(struct mrb_state *, struct mrb_irep *, mrb_code *, mrb_value *);36 void (*tmp)(struct mrb_state *, struct mrb_irep *, const mrb_code *, mrb_value *); 37 37 mrb_value ruby_code; 38 38 mrb_value s; … … 48 48 v = mrb_obj_value(mrb->exc); 49 49 mrb->exc = 0; 50 } 51 else if (direct_eval) { 52 recv = dbg->regs[0]; 53 54 v = mrb_funcall(mrb, recv, expr, 0); 50 55 } 51 56 else { … … 70 75 } 71 76 72 s = mrb_ funcall(mrb, v, "inspect", 0);77 s = mrb_inspect(mrb, v); 73 78 74 79 /* enable code_fetch_hook */ -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.h
r331 r439 9 9 #include "mrdb.h" 10 10 11 mrb_value mrb_debug_eval(mrb_state*, mrb_debug_context*, const char*, size_t, mrb_bool* );11 mrb_value mrb_debug_eval(mrb_state*, mrb_debug_context*, const char*, size_t, mrb_bool*, int); 12 12 13 13 #endif /* APIPRINT_H_ */ -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c
r331 r439 243 243 244 244 mrb_debug_bptype 245 parse_breakcommand(mr db_state *mrdb, const char **file, uint32_t *line, char **cname, char **method)245 parse_breakcommand(mrb_state *mrb, mrdb_state *mrdb, const char **file, uint32_t *line, char **cname, char **method) 246 246 { 247 247 mrb_debug_context *dbg = mrdb->dbg; … … 275 275 if (l <= 65535) { 276 276 *line = l; 277 *file = (body == args)? mrb_debug_get_filename( dbg->irep, (uint32_t)(dbg->pc - dbg->irep->iseq)): args;277 *file = (body == args)? mrb_debug_get_filename(mrb, dbg->irep, dbg->pc - dbg->irep->iseq): args; 278 278 } 279 279 else { … … 333 333 int32_t ret; 334 334 335 type = parse_breakcommand(mr db, &file, &line, &cname, &method);335 type = parse_breakcommand(mrb, mrdb, &file, &line, &cname, &method); 336 336 switch (type) { 337 337 case MRB_DEBUG_BPTYPE_LINE: -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c
r331 r439 81 81 "Status of specified breakpoints (all user-settable breakpoints if no argument).\n" 82 82 "Arguments are breakpoint numbers with spaces in between.\n" 83 }, 84 { 85 "i[nfo]", "l[ocals]", "Print name of local variables", 86 "Usage: info locals\n" 87 "\n" 88 "Print name of local variables.\n" 83 89 }, 84 90 { … … 134 140 listcmd_parser_state_new(mrb_state *mrb) 135 141 { 136 listcmd_parser_state *st = mrb_malloc(mrb, sizeof(listcmd_parser_state));142 listcmd_parser_state *st = (listcmd_parser_state*)mrb_malloc(mrb, sizeof(listcmd_parser_state)); 137 143 memset(st, 0, sizeof(listcmd_parser_state)); 138 144 return st; … … 228 234 229 235 if (len > 0) { 230 st->filename = mrb_malloc(mrb, len + 1);236 st->filename = (char*)mrb_malloc(mrb, len + 1); 231 237 strncpy(st->filename, *sp, len); 232 238 st->filename[len] = '\0'; … … 243 249 { 244 250 size_t len; 245 char *p, *s; 251 const char *p; 252 char *s; 246 253 247 254 if (filename == NULL) { … … 256 263 } 257 264 258 s = mrb_malloc(mrb, len + strlen(ext) + 1);265 s = (char*)mrb_malloc(mrb, len + strlen(ext) + 1); 259 266 memset(s, '\0', len + strlen(ext) + 1); 260 267 strncpy(s, filename, len); … … 326 333 check_cmd_pattern(const char *pattern, const char *cmd) 327 334 { 328 c har *lbracket, *rbracket, *p, *q;335 const char *lbracket, *rbracket, *p, *q; 329 336 330 337 if (pattern == NULL && cmd == NULL) { … … 495 502 if (mrdb->dbg->xm == DBG_QUIT) { 496 503 struct RClass *exc; 497 exc = mrb_define_class(mrb, "DebuggerExit", mrb _class_get(mrb, "Exception"));504 exc = mrb_define_class(mrb, "DebuggerExit", mrb->eException_class); 498 505 mrb_raise(mrb, exc, "Exit mrdb."); 499 506 } -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/cmdprint.c
r331 r439 19 19 mrb_value expr; 20 20 mrb_value result; 21 mrb_value s;22 21 uint8_t wcnt; 23 22 int ai; … … 37 36 } 38 37 39 result = mrb_debug_eval(mrb, mrdb->dbg, RSTRING_PTR(expr), RSTRING_LEN(expr), NULL );38 result = mrb_debug_eval(mrb, mrdb->dbg, RSTRING_PTR(expr), RSTRING_LEN(expr), NULL, 0); 40 39 41 40 /* $print_no = result */ 42 s = mrb_str_cat_lit(mrb, result, "\0"); 43 printf("$%lu = %s\n", (unsigned long)mrdb->print_no++, RSTRING_PTR(s)); 41 printf("$%lu = ", (unsigned long)mrdb->print_no++); 42 fwrite(RSTRING_PTR(result), RSTRING_LEN(result), 1, stdout); 43 putc('\n', stdout); 44 44 45 45 if (mrdb->print_no == 0) { … … 57 57 return dbgcmd_print(mrb, mrdb); 58 58 } 59 60 dbgcmd_state 61 dbgcmd_info_local(mrb_state *mrb, mrdb_state *mrdb) 62 { 63 mrb_value result; 64 mrb_value s; 65 int ai; 66 67 ai = mrb_gc_arena_save(mrb); 68 69 result = mrb_debug_eval(mrb, mrdb->dbg, "local_variables", 0, NULL, 1); 70 71 s = mrb_str_cat_lit(mrb, result, "\0"); 72 printf("$%lu = %s\n", (unsigned long)mrdb->print_no++, RSTRING_PTR(s)); 73 74 if (mrdb->print_no == 0) { 75 mrdb->print_no = 1; 76 } 77 78 mrb_gc_arena_restore(mrb, ai); 79 80 return DBGST_PROMPT; 81 } -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c
r331 r439 20 20 struct RClass *exc; 21 21 puts("Start it from the beginning."); 22 exc = mrb_define_class(mrb, "DebuggerRestart", mrb _class_get(mrb, "Exception"));22 exc = mrb_define_class(mrb, "DebuggerRestart", mrb->eException_class); 23 23 mrb_raise(mrb, exc, "Restart mrdb."); 24 24 } -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c
r331 r439 6 6 #include <stdlib.h> 7 7 #include <string.h> 8 #include <stdio.h>9 8 #include <ctype.h> 10 9 … … 53 52 {"help", NULL, 1, 0, 1, DBGCMD_HELP, dbgcmd_help}, /* h[elp] */ 54 53 {"info", "breakpoints", 1, 1, 1, DBGCMD_INFO_BREAK, dbgcmd_info_break}, /* i[nfo] b[reakpoints] */ 54 {"info", "locals", 1, 1, 0, DBGCMD_INFO_LOCAL, dbgcmd_info_local}, /* i[nfo] l[ocals] */ 55 55 {"list", NULL, 1, 0, 1, DBGCMD_LIST, dbgcmd_list}, /* l[ist] */ 56 56 {"print", NULL, 1, 0, 0, DBGCMD_PRINT, dbgcmd_print}, /* p[rint] */ … … 185 185 mrb_debug_context_new(mrb_state *mrb) 186 186 { 187 mrb_debug_context *dbg = mrb_malloc(mrb, sizeof(mrb_debug_context));187 mrb_debug_context *dbg = (mrb_debug_context*)mrb_malloc(mrb, sizeof(mrb_debug_context)); 188 188 189 189 memset(dbg, 0, sizeof(mrb_debug_context)); … … 224 224 mrdb_state_new(mrb_state *mrb) 225 225 { 226 mrdb_state *mrdb = mrb_malloc(mrb, sizeof(mrdb_state));226 mrdb_state *mrdb = (mrdb_state*)mrb_malloc(mrb, sizeof(mrdb_state)); 227 227 228 228 memset(mrdb, 0, sizeof(mrdb_state)); 229 229 230 230 mrdb->dbg = mrb_debug_context_get(mrb); 231 mrdb->command = mrb_malloc(mrb, MAX_COMMAND_LINE+1);231 mrdb->command = (char*)mrb_malloc(mrb, MAX_COMMAND_LINE+1); 232 232 mrdb->print_no = 1; 233 233 … … 505 505 506 506 static int32_t 507 check_method_breakpoint(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value *regs)507 check_method_breakpoint(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, mrb_value *regs) 508 508 { 509 509 struct RClass* c; … … 511 511 int32_t bpno; 512 512 mrb_bool isCfunc; 513 struct mrb_insn_data insn; 513 514 514 515 mrb_debug_context *dbg = mrb_debug_context_get(mrb); … … 518 519 dbg->method_bpno = 0; 519 520 520 switch(GET_OPCODE(*pc)) { 521 insn = mrb_decode_insn(pc); 522 switch(insn.insn) { 521 523 case OP_SEND: 522 524 case OP_SENDB: 523 c = mrb_class(mrb, regs[ GETARG_A(*pc)]);524 sym = irep->syms[ GETARG_B(*pc)];525 c = mrb_class(mrb, regs[insn.a]); 526 sym = irep->syms[insn.b]; 525 527 break; 526 528 case OP_SUPER: … … 544 546 545 547 static void 546 mrb_code_fetch_hook(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value *regs)548 mrb_code_fetch_hook(mrb_state *mrb, mrb_irep *irep, const mrb_code *pc, mrb_value *regs) 547 549 { 548 550 const char *file; … … 567 569 } 568 570 569 file = mrb_debug_get_filename( irep, (uint32_t)(pc - irep->iseq));570 line = mrb_debug_get_line( irep, (uint32_t)(pc - irep->iseq));571 file = mrb_debug_get_filename(mrb, irep, pc - irep->iseq); 572 line = mrb_debug_get_line(mrb, irep, pc - irep->iseq); 571 573 572 574 switch (dbg->xm) { -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h
r331 r439 24 24 DBGCMD_BREAK, 25 25 DBGCMD_INFO_BREAK, 26 DBGCMD_INFO_LOCAL, 26 27 DBGCMD_WATCH, 27 28 DBGCMD_INFO_WATCH, … … 105 106 struct mrb_irep *root_irep; 106 107 struct mrb_irep *irep; 107 mrb_code *pc;108 const mrb_code *pc; 108 109 mrb_value *regs; 109 110 … … 152 153 dbgcmd_state dbgcmd_break(mrb_state*, mrdb_state*); 153 154 dbgcmd_state dbgcmd_info_break(mrb_state*, mrdb_state*); 155 dbgcmd_state dbgcmd_info_local(mrb_state*, mrdb_state*); 154 156 dbgcmd_state dbgcmd_delete(mrb_state*, mrdb_state*); 155 157 dbgcmd_state dbgcmd_enable(mrb_state*, mrdb_state*); -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-debugger/tools/mrdb/mrdbconf.h
r321 r439 6 6 #ifndef MRDBCONF_H 7 7 #define MRDBCONF_H 8 9 #ifndef MRB_ENABLE_DEBUG_HOOK 10 # error mruby-bin-debugger need 'MRB_ENABLE_DEBUG_HOOK' configuration in your 'build_config.rb' 11 #endif 12 13 #ifdef MRB_DISABLE_STDIO 14 # error mruby-bin-debugger conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb' 15 #endif 8 16 9 17 /* configuration options: */ -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-mirb/bintest/mirb.rb
r321 r439 11 11 assert_true o.include?('=> 3') 12 12 end 13 14 assert('mirb -d option') do 15 o, _ = Open3.capture2('bin/mirb', :stdin_data => "$DEBUG\n") 16 assert_true o.include?('=> false') 17 o, _ = Open3.capture2('bin/mirb -d', :stdin_data => "$DEBUG\n") 18 assert_true o.include?('=> true') 19 end 20 21 assert('mirb -r option') do 22 lib = Tempfile.new('lib.rb') 23 lib.write <<EOS 24 class Hoge 25 def hoge 26 :hoge 27 end 28 end 29 EOS 30 lib.flush 31 32 o, _ = Open3.capture2("bin/mirb -r #{lib.path}", :stdin_data => "Hoge.new.hoge\n") 33 assert_true o.include?('=> :hoge') 34 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
r331 r439 7 7 */ 8 8 9 #include <mruby.h> 10 11 #ifdef MRB_DISABLE_STDIO 12 # error mruby-bin-mirb conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb' 13 #endif 14 15 #include <mruby/array.h> 16 #include <mruby/proc.h> 17 #include <mruby/compile.h> 18 #include <mruby/dump.h> 19 #include <mruby/string.h> 20 #include <mruby/variable.h> 21 #include <mruby/throw.h> 22 9 23 #include <stdlib.h> 10 24 #include <string.h> 11 #include <stdio.h>12 25 #include <ctype.h> 13 26 … … 20 33 #define MIRB_ADD_HISTORY(line) add_history(line) 21 34 #define MIRB_READLINE(ch) readline(ch) 35 #if !defined(RL_READLINE_VERSION) || RL_READLINE_VERSION < 0x600 36 /* libedit & older readline do not have rl_free() */ 37 #define MIRB_LINE_FREE(line) free(line) 38 #else 39 #define MIRB_LINE_FREE(line) rl_free(line) 40 #endif 22 41 #define MIRB_WRITE_HISTORY(path) write_history(path) 23 42 #define MIRB_READ_HISTORY(path) read_history(path) … … 28 47 #define MIRB_ADD_HISTORY(line) linenoiseHistoryAdd(line) 29 48 #define MIRB_READLINE(ch) linenoise(ch) 49 #define MIRB_LINE_FREE(line) linenoiseFree(line) 30 50 #define MIRB_WRITE_HISTORY(path) linenoiseHistorySave(path) 31 51 #define MIRB_READ_HISTORY(path) linenoiseHistoryLoad(history_path) … … 42 62 #define SIGJMP_BUF jmp_buf 43 63 #endif 44 45 #include <mruby.h>46 #include <mruby/array.h>47 #include <mruby/proc.h>48 #include <mruby/compile.h>49 #include <mruby/string.h>50 64 51 65 #ifdef ENABLE_READLINE … … 89 103 { 90 104 mrb_value val; 105 char* msg; 91 106 92 107 val = mrb_funcall(mrb, obj, "inspect", 0); … … 102 117 val = mrb_obj_as_string(mrb, obj); 103 118 } 104 fwrite(RSTRING_PTR(val), RSTRING_LEN(val), 1, stdout); 119 msg = mrb_locale_from_utf8(RSTRING_PTR(val), (int)RSTRING_LEN(val)); 120 fwrite(msg, strlen(msg), 1, stdout); 121 mrb_locale_free(msg); 105 122 putc('\n', stdout); 106 123 } … … 115 132 /* check for heredoc */ 116 133 if (parser->parsing_heredoc != NULL) return TRUE; 117 if (parser->heredoc_end_now) {118 parser->heredoc_end_now = FALSE;119 return FALSE;120 }121 134 122 135 /* check for unterminated string */ … … 210 223 FILE *rfp; 211 224 mrb_bool verbose : 1; 225 mrb_bool debug : 1; 212 226 int argc; 213 227 char** argv; 228 int libc; 229 char **libv; 214 230 }; 215 231 … … 219 235 static const char *const usage_msg[] = { 220 236 "switches:", 237 "-d set $DEBUG to true (same as `mruby -d`)", 238 "-r library same as `mruby -r`", 221 239 "-v print version number, then run in verbose mode", 222 240 "--verbose run in verbose mode", … … 227 245 const char *const *p = usage_msg; 228 246 229 printf("Usage: %s [switches] \n", name);247 printf("Usage: %s [switches] [programfile] [arguments]\n", name); 230 248 while (*p) 231 249 printf(" %s\n", *p++); 232 250 } 233 251 252 static char * 253 dup_arg_item(mrb_state *mrb, const char *item) 254 { 255 size_t buflen = strlen(item) + 1; 256 char *buf = (char*)mrb_malloc(mrb, buflen); 257 memcpy(buf, item, buflen); 258 return buf; 259 } 260 234 261 static int 235 262 parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args) 236 263 { 264 char **origargv = argv; 237 265 static const struct _args args_zero = { 0 }; 238 266 … … 245 273 item = argv[0] + 1; 246 274 switch (*item++) { 275 case 'd': 276 args->debug = TRUE; 277 break; 278 case 'r': 279 if (!item[0]) { 280 if (argc <= 1) { 281 printf("%s: No library specified for -r\n", *origargv); 282 return EXIT_FAILURE; 283 } 284 argc--; argv++; 285 item = argv[0]; 286 } 287 if (args->libc == 0) { 288 args->libv = (char**)mrb_malloc(mrb, sizeof(char*)); 289 } 290 else { 291 args->libv = (char**)mrb_realloc(mrb, args->libv, sizeof(char*) * (args->libc + 1)); 292 } 293 args->libv[args->libc++] = dup_arg_item(mrb, item); 294 break; 247 295 case 'v': 248 296 if (!args->verbose) mrb_show_version(mrb); … … 290 338 fclose(args->rfp); 291 339 mrb_free(mrb, args->argv); 340 if (args->libc) { 341 while (args->libc--) { 342 mrb_free(mrb, args->libv[args->libc]); 343 } 344 mrb_free(mrb, args->libv); 345 } 292 346 mrb_close(mrb); 293 347 } … … 324 378 325 379 /* skip preceding spaces */ 326 while (*p && isspace((unsigned char)*p)) {380 while (*p && ISSPACE(*p)) { 327 381 p++; 328 382 } … … 334 388 /* skip trailing spaces */ 335 389 while (*p) { 336 if (! isspace((unsigned char)*p)) return 0;390 if (!ISSPACE(*p)) return 0; 337 391 p++; 338 392 } … … 354 408 { 355 409 MIRB_SIGLONGJMP(ctrl_c_buf, 1); 410 } 411 #endif 412 413 #ifndef DISABLE_MIRB_UNDERSCORE 414 void decl_lv_underscore(mrb_state *mrb, mrbc_context *cxt) 415 { 416 struct RProc *proc; 417 struct mrb_parser_state *parser; 418 419 parser = mrb_parse_string(mrb, "_=nil", cxt); 420 if (parser == NULL) { 421 fputs("create parser state error\n", stderr); 422 mrb_close(mrb); 423 exit(EXIT_FAILURE); 424 } 425 426 proc = mrb_generate_code(mrb, parser); 427 mrb_vm_run(mrb, proc, mrb_top_self(mrb), 0); 428 429 mrb_parser_free(parser); 356 430 } 357 431 #endif … … 404 478 } 405 479 mrb_define_global_const(mrb, "ARGV", ARGV); 480 mrb_gv_set(mrb, mrb_intern_lit(mrb, "$DEBUG"), mrb_bool_value(args.debug)); 406 481 407 482 #ifdef ENABLE_READLINE … … 420 495 421 496 cxt = mrbc_context_new(mrb); 497 498 #ifndef DISABLE_MIRB_UNDERSCORE 499 decl_lv_underscore(mrb, cxt); 500 #endif 501 502 /* Load libraries */ 503 for (i = 0; i < args.libc; i++) { 504 FILE *lfp = fopen(args.libv[i], "r"); 505 if (lfp == NULL) { 506 printf("Cannot open library file. (%s)\n", args.libv[i]); 507 cleanup(mrb, &args); 508 return EXIT_FAILURE; 509 } 510 mrb_load_file_cxt(mrb, lfp, cxt); 511 fclose(lfp); 512 } 513 422 514 cxt->capture_errors = TRUE; 423 515 cxt->lineno = 1; … … 429 521 while (TRUE) { 430 522 char *utf8; 431 523 struct mrb_jmpbuf c_jmp; 524 525 MRB_TRY(&c_jmp); 526 mrb->jmp = &c_jmp; 432 527 if (args.rfp) { 433 528 if (fgets(last_code_line, sizeof(last_code_line)-1, args.rfp) != NULL) … … 490 585 strcat(last_code_line, "\n"); 491 586 MIRB_ADD_HISTORY(line); 492 free(line); 493 #endif 494 495 done: 496 587 MIRB_LINE_FREE(line); 588 #endif 589 590 done: 497 591 if (code_block_open) { 498 592 if (strlen(ruby_code)+strlen(last_code_line) > sizeof(ruby_code)-1) { … … 529 623 } 530 624 else { 625 if (0 < parser->nwarn) { 626 /* warning */ 627 char* msg = mrb_locale_from_utf8(parser->warn_buffer[0].message, -1); 628 printf("line %d: %s\n", parser->warn_buffer[0].lineno, msg); 629 mrb_locale_free(msg); 630 } 531 631 if (0 < parser->nerr) { 532 632 /* syntax error */ 533 printf("line %d: %s\n", parser->error_buffer[0].lineno, parser->error_buffer[0].message); 633 char* msg = mrb_locale_from_utf8(parser->error_buffer[0].message, -1); 634 printf("line %d: %s\n", parser->error_buffer[0].lineno, msg); 635 mrb_locale_free(msg); 534 636 } 535 637 else { … … 544 646 if (args.verbose) { 545 647 mrb_codedump_all(mrb, proc); 648 } 649 /* adjust stack length of toplevel environment */ 650 if (mrb->c->cibase->env) { 651 struct REnv *e = mrb->c->cibase->env; 652 if (e && MRB_ENV_STACK_LEN(e) < proc->body.irep->nlocals) { 653 MRB_ENV_SET_STACK_LEN(e, proc->body.irep->nlocals); 654 } 546 655 } 547 656 /* pass a proc for evaluation */ … … 563 672 } 564 673 p(mrb, result, 1); 674 #ifndef DISABLE_MIRB_UNDERSCORE 675 *(mrb->c->stack + 1) = result; 676 #endif 565 677 } 566 678 } … … 571 683 mrb_parser_free(parser); 572 684 cxt->lineno++; 685 MRB_CATCH(&c_jmp) { 686 p(mrb, mrb_obj_value(mrb->exc), 0); 687 mrb->exc = 0; 688 } 689 MRB_END_EXC(&c_jmp); 573 690 } 574 691 … … 578 695 #endif 579 696 697 if (args.rfp) fclose(args.rfp); 698 mrb_free(mrb, args.argv); 699 if (args.libv) { 700 for (i = 0; i < args.libc; ++i) { 701 mrb_free(mrb, args.libv[i]); 702 } 703 mrb_free(mrb, args.libv); 704 } 580 705 mrbc_context_free(mrb, cxt); 581 706 mrb_close(mrb); -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-mrbc/mrbgem.rake
r321 r439 9 9 mrbc_objs = Dir.glob("#{spec.dir}/tools/mrbc/*.c").map { |f| objfile(f.pathmap("#{spec.build_dir}/tools/mrbc/%n")) }.flatten 10 10 11 file exec => mrbc_objs + [ libfile("#{build.build_dir}/lib/libmruby_core")] do |t|11 file exec => mrbc_objs + [build.libmruby_core_static] do |t| 12 12 build.linker.run t.name, t.prerequisites 13 13 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c
r331 r439 1 #include <stdio.h> 1 #include <mruby.h> 2 3 #ifdef MRB_DISABLE_STDIO 4 # error mruby-bin-mrbc conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb' 5 #endif 6 2 7 #include <stdlib.h> 3 8 #include <string.h> 4 #include <mruby.h>5 9 #include <mruby/compile.h> 6 10 #include <mruby/dump.h> … … 19 23 mrb_bool check_syntax : 1; 20 24 mrb_bool verbose : 1; 25 mrb_bool remove_lv : 1; 21 26 unsigned int flags : 4; 22 27 }; … … 34 39 "-e generate little endian iseq data", 35 40 "-E generate big endian iseq data", 41 "--remove-lv remove local variables", 36 42 "--verbose run at verbose mode", 37 43 "--version print the version", … … 70 76 parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args) 71 77 { 72 char *outfile = NULL;73 78 static const struct mrbc_args args_zero = { 0 }; 74 79 int i; … … 85 90 if (args->outfile) { 86 91 fprintf(stderr, "%s: an output file is already specified. (%s)\n", 87 args->prog, outfile);92 args->prog, args->outfile); 88 93 return -1; 89 94 } … … 143 148 exit(EXIT_SUCCESS); 144 149 } 150 else if (strcmp(argv[i] + 2, "remove-lv") == 0) { 151 args->remove_lv = TRUE; 152 break; 153 } 145 154 return -1; 146 155 default: … … 179 188 } 180 189 fn = args->argv[args->idx++]; 181 p->f = fopen(fn, "r ");190 p->f = fopen(fn, "rb"); 182 191 if (p->f == NULL) { 183 192 fprintf(stderr, "%s: cannot open program file. (%s)\n", args->prog, fn); … … 206 215 else { 207 216 need_close = TRUE; 208 if ((infile = fopen(input, "r ")) == NULL) {217 if ((infile = fopen(input, "rb")) == NULL) { 209 218 fprintf(stderr, "%s: cannot open program file. (%s)\n", args->prog, input); 210 219 return mrb_nil_value(); … … 233 242 mrb_irep *irep = proc->body.irep; 234 243 244 if (args->remove_lv) { 245 mrb_irep_remove_lv(mrb, irep); 246 } 235 247 if (args->initname) { 236 248 n = mrb_dump_irep_cfunc(mrb, irep, args->flags, wfp, args->initname); -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-mruby/bintest/mruby.rb
r331 r439 1 1 require 'tempfile' 2 require 'open3' 3 4 def assert_mruby(exp_out, exp_err, exp_success, args) 5 out, err, stat = Open3.capture3(cmd("mruby"), *args) 6 assert "assert_mruby" do 7 assert_operator(exp_out, :===, out, "standard output") 8 assert_operator(exp_err, :===, err, "standard error") 9 assert_equal(exp_success, stat.success?, "exit success?") 10 end 11 end 2 12 3 13 assert('regression for #1564') do 4 o = `#{cmd('mruby')} -e #{shellquote('<<')} 2>&1` 5 assert_include o, "-e:1:2: syntax error" 6 o = `#{cmd('mruby')} -e #{shellquote('<<-')} 2>&1` 7 assert_include o, "-e:1:3: syntax error" 14 assert_mruby("", /\A-e:1:2: syntax error, .*\n\z/, false, %w[-e <<]) 15 assert_mruby("", /\A-e:1:3: syntax error, .*\n\z/, false, %w[-e <<-]) 8 16 end 9 17 … … 13 21 system "#{cmd('mrbc')} -g -o #{bin.path} #{script.path}" 14 22 o = `#{cmd('mruby')} -b #{bin.path}`.strip 15 assert_equal o, '"ok"'23 assert_equal '"ok"', o 16 24 end 17 25 … … 30 38 # one liner 31 39 assert_equal '"-e"', `#{cmd('mruby')} -e #{shellquote('p $0')}`.chomp 40 end 41 42 assert 'ARGV value' do 43 assert_mruby(%{["ab", "cde"]\n}, "", true, %w[-e p(ARGV) ab cde]) 44 assert_mruby("[]\n", "", true, %w[-e p(ARGV)]) 45 end 46 47 assert('float literal') do 48 script, bin = Tempfile.new('test.rb'), Tempfile.new('test.mrb') 49 File.write script.path, 'p [3.21, 2e308.infinite?, -2e308.infinite?]' 50 system "#{cmd('mrbc')} -g -o #{bin.path} #{script.path}" 51 assert_equal "[3.21, 1, -1]", `#{cmd('mruby')} -b #{bin.path}`.chomp! 32 52 end 33 53 … … 59 79 assert_equal 0, $?.exitstatus 60 80 end 81 82 assert('mruby -c option') do 83 assert_mruby("Syntax OK\n", "", true, ["-c", "-e", "p 1"]) 84 assert_mruby("", /\A-e:1:7: syntax error, .*\n\z/, false, ["-c", "-e", "p 1; 1."]) 85 end 86 87 assert('mruby -d option') do 88 assert_mruby("false\n", "", true, ["-e", "p $DEBUG"]) 89 assert_mruby("true\n", "", true, ["-dep $DEBUG"]) 90 end 91 92 assert('mruby -e option (no code specified)') do 93 assert_mruby("", /\A.*: No code specified for -e\n\z/, false, %w[-e]) 94 end 95 96 assert('mruby -h option') do 97 assert_mruby(/\AUsage: #{Regexp.escape cmd("mruby")} .*/m, "", true, %w[-h]) 98 end 99 100 assert('mruby -r option') do 101 lib = Tempfile.new('lib.rb') 102 lib.write <<EOS 103 class Hoge 104 def hoge 105 :hoge 106 end 107 end 108 EOS 109 lib.flush 110 111 script = Tempfile.new('test.rb') 112 script.write <<EOS 113 print Hoge.new.hoge 114 EOS 115 script.flush 116 assert_equal 'hoge', `#{cmd('mruby')} -r #{lib.path} #{script.path}` 117 assert_equal 0, $?.exitstatus 118 119 assert_equal 'hogeClass', `#{cmd('mruby')} -r #{lib.path} -r #{script.path} -e #{shellquote('print Hoge.class')}` 120 assert_equal 0, $?.exitstatus 121 end 122 123 assert('mruby -r option (no library specified)') do 124 assert_mruby("", /\A.*: No library specified for -r\n\z/, false, %w[-r]) 125 end 126 127 assert('mruby -r option (file not found)') do 128 assert_mruby("", /\A.*: Cannot open library file: .*\n\z/, false, %w[-r _no_exists_]) 129 end 130 131 assert('mruby -v option') do 132 ver_re = '\Amruby \d+\.\d+\.\d+ \(\d+-\d+-\d+\)\n' 133 assert_mruby(/#{ver_re}\z/, "", true, %w[-v]) 134 assert_mruby(/#{ver_re}^[^\n]*NODE.*\n:end\n\z/m, "", true, %w[-v -e p(:end)]) 135 end 136 137 assert('mruby --verbose option') do 138 assert_mruby(/\A[^\n]*NODE.*\n:end\n\z/m, "", true, %w[--verbose -e p(:end)]) 139 end 140 141 assert('mruby --') do 142 assert_mruby(%{["-x", "1"]\n}, "", true, %w[-e p(ARGV) -- -x 1]) 143 end 144 145 assert('mruby invalid short option') do 146 assert_mruby("", /\A.*: invalid option -1 .*\n\z/, false, %w[-1]) 147 end 148 149 assert('mruby invalid long option') do 150 assert_mruby("", /\A.*: invalid option --longopt .*\n\z/, false, %w[--longopt]) 151 end 152 153 assert('unhandled exception') do 154 assert_mruby("", /\bEXCEPTION\b.*\n\z/, false, %w[-e raise("EXCEPTION")]) 155 end 156 157 assert('program file not found') do 158 assert_mruby("", /\A.*: Cannot open program file: .*\n\z/, false, %w[_no_exists_]) 159 end 160 161 assert('codegen error') do 162 code = "def f(#{(1..100).map{|n| "a#{n}"} * ","}); end" 163 assert_mruby("", /\Acodegen error:.*\n\z/, false, ["-e", code]) 164 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-mruby/mrbgem.rake
r331 r439 6 6 spec.add_dependency('mruby-compiler', :core => 'mruby-compiler') 7 7 spec.add_dependency('mruby-error', :core => 'mruby-error') 8 spec.add_test_dependency('mruby-print', :core => 'mruby-print') 8 9 9 10 if build.cxx_exception_enabled? 10 @objs << build.compile_as_cxx("#{spec.dir}/tools/mruby/mruby.c", "#{spec.build_dir}/tools/mruby/mruby.cxx") 11 @objs.delete_if { |v| v == objfile("#{spec.build_dir}/tools/mruby/mruby") } 11 build.compile_as_cxx("#{spec.dir}/tools/mruby/mruby.c", "#{spec.build_dir}/tools/mruby/mruby.cxx") 12 12 end 13 13 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
r331 r439 1 #include <stdio.h> 1 #include <mruby.h> 2 3 #ifdef MRB_DISABLE_STDIO 4 # error mruby-bin-mruby conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb' 5 #endif 6 2 7 #include <stdlib.h> 3 8 #include <string.h> 4 #include <mruby.h>5 9 #include <mruby/array.h> 6 10 #include <mruby/compile.h> … … 8 12 #include <mruby/variable.h> 9 13 10 #ifdef MRB_DISABLE_STDIO11 static void12 p(mrb_state *mrb, mrb_value obj)13 {14 mrb_value val = mrb_inspect(mrb, obj);15 16 fwrite(RSTRING_PTR(val), RSTRING_LEN(val), 1, stdout);17 putc('\n', stdout);18 }19 #else20 #define p(mrb,obj) mrb_p(mrb,obj)21 #endif22 23 14 struct _args { 24 15 FILE *rfp; 25 char *cmdline;16 char *cmdline; 26 17 mrb_bool fname : 1; 27 18 mrb_bool mrbfile : 1; 28 19 mrb_bool check_syntax : 1; 29 20 mrb_bool verbose : 1; 21 mrb_bool version : 1; 22 mrb_bool debug : 1; 30 23 int argc; 31 char** argv; 24 char **argv; 25 int libc; 26 char **libv; 27 }; 28 29 struct options { 30 int argc; 31 char **argv; 32 char *program; 33 char *opt; 34 char short_opt[2]; 32 35 }; 33 36 … … 39 42 "-b load and execute RiteBinary (mrb) file", 40 43 "-c check syntax only", 44 "-d set debugging flags (set $DEBUG to true)", 41 45 "-e 'command' one line of script", 46 "-r library load the library before executing your script", 42 47 "-v print version number, then run in verbose mode", 43 48 "--verbose run in verbose mode", … … 48 53 const char *const *p = usage_msg; 49 54 50 printf("Usage: %s [switches] programfile\n", name);55 printf("Usage: %s [switches] [programfile] [arguments]\n", name); 51 56 while (*p) 52 57 printf(" %s\n", *p++); 53 58 } 54 59 60 static void 61 options_init(struct options *opts, int argc, char **argv) 62 { 63 opts->argc = argc; 64 opts->argv = argv; 65 opts->program = *argv; 66 *opts->short_opt = 0; 67 } 68 69 static const char * 70 options_opt(struct options *opts) 71 { 72 /* concatenated short options (e.g. `-cv`) */ 73 if (*opts->short_opt && *++opts->opt) { 74 short_opt: 75 opts->short_opt[0] = *opts->opt; 76 opts->short_opt[1] = 0; 77 return opts->short_opt; 78 } 79 80 while (++opts->argv, --opts->argc) { 81 opts->opt = *opts->argv; 82 83 /* empty || not start with `-` || `-` */ 84 if (!opts->opt[0] || opts->opt[0] != '-' || !opts->opt[1]) return NULL; 85 86 if (opts->opt[1] == '-') { 87 /* `--` */ 88 if (!opts->opt[2]) { 89 ++opts->argv, --opts->argc; 90 return NULL; 91 } 92 /* long option */ 93 opts->opt += 2; 94 *opts->short_opt = 0; 95 return opts->opt; 96 } 97 else { 98 /* short option */ 99 ++opts->opt; 100 goto short_opt; 101 } 102 } 103 return NULL; 104 } 105 106 static const char * 107 options_arg(struct options *opts) 108 { 109 if (*opts->short_opt && opts->opt[1]) { 110 /* concatenated short option and option argument (e.g. `-rLIBRARY`) */ 111 *opts->short_opt = 0; 112 return opts->opt + 1; 113 } 114 --opts->argc, ++opts->argv; 115 return opts->argc ? *opts->argv : NULL; 116 } 117 118 static char * 119 dup_arg_item(mrb_state *mrb, const char *item) 120 { 121 size_t buflen = strlen(item) + 1; 122 char *buf = (char*)mrb_malloc(mrb, buflen); 123 memcpy(buf, item, buflen); 124 return buf; 125 } 126 55 127 static int 56 128 parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args) 57 129 { 58 char **origargv = argv;59 130 static const struct _args args_zero = { 0 }; 131 struct options opts[1]; 132 const char *opt, *item; 60 133 61 134 *args = args_zero; 62 63 for (argc--,argv++; argc > 0; argc--,argv++) { 64 char *item; 65 if (argv[0][0] != '-') break; 66 67 if (strlen(*argv) <= 1) { 68 argc--; argv++; 69 args->rfp = stdin; 70 break; 71 } 72 73 item = argv[0] + 1; 74 switch (*item++) { 75 case 'b': 135 options_init(opts, argc, argv); 136 while ((opt = options_opt(opts))) { 137 if (strcmp(opt, "b") == 0) { 76 138 args->mrbfile = TRUE; 77 break;78 case 'c':139 } 140 else if (strcmp(opt, "c") == 0) { 79 141 args->check_syntax = TRUE; 80 break; 81 case 'e': 82 if (item[0]) { 83 goto append_cmdline; 84 } 85 else if (argc > 1) { 86 argc--; argv++; 87 item = argv[0]; 88 append_cmdline: 142 } 143 else if (strcmp(opt, "d") == 0) { 144 args->debug = TRUE; 145 } 146 else if (strcmp(opt, "e") == 0) { 147 if ((item = options_arg(opts))) { 89 148 if (!args->cmdline) { 90 size_t buflen; 91 char *buf; 92 93 buflen = strlen(item) + 1; 94 buf = (char *)mrb_malloc(mrb, buflen); 95 memcpy(buf, item, buflen); 96 args->cmdline = buf; 149 args->cmdline = dup_arg_item(mrb, item); 97 150 } 98 151 else { … … 109 162 } 110 163 else { 111 printf("%s: No code specified for -e\n", *origargv); 112 return EXIT_SUCCESS; 113 } 114 break; 115 case 'v': 116 if (!args->verbose) mrb_show_version(mrb); 164 fprintf(stderr, "%s: No code specified for -e\n", opts->program); 165 return EXIT_FAILURE; 166 } 167 } 168 else if (strcmp(opt, "h") == 0) { 169 usage(opts->program); 170 exit(EXIT_SUCCESS); 171 } 172 else if (strcmp(opt, "r") == 0) { 173 if ((item = options_arg(opts))) { 174 if (args->libc == 0) { 175 args->libv = (char**)mrb_malloc(mrb, sizeof(char*)); 176 } 177 else { 178 args->libv = (char**)mrb_realloc(mrb, args->libv, sizeof(char*) * (args->libc + 1)); 179 } 180 args->libv[args->libc++] = dup_arg_item(mrb, item); 181 } 182 else { 183 fprintf(stderr, "%s: No library specified for -r\n", opts->program); 184 return EXIT_FAILURE; 185 } 186 } 187 else if (strcmp(opt, "v") == 0) { 188 if (!args->verbose) { 189 mrb_show_version(mrb); 190 args->version = TRUE; 191 } 117 192 args->verbose = TRUE; 118 break;119 case '-':120 if (strcmp((*argv) + 2, "version") == 0) {121 mrb_show_version(mrb);122 exit(EXIT_SUCCESS);123 }124 else if (strcmp((*argv) + 2, "verbose") == 0) {125 args->verbose = TRUE;126 break;127 }128 e lse if (strcmp((*argv) + 2, "copyright") == 0) {129 mrb_show_copyright(mrb);130 exit(EXIT_SUCCESS);131 }132 default:193 } 194 else if (strcmp(opt, "version") == 0) { 195 mrb_show_version(mrb); 196 exit(EXIT_SUCCESS); 197 } 198 else if (strcmp(opt, "verbose") == 0) { 199 args->verbose = TRUE; 200 } 201 else if (strcmp(opt, "copyright") == 0) { 202 mrb_show_copyright(mrb); 203 exit(EXIT_SUCCESS); 204 } 205 else { 206 fprintf(stderr, "%s: invalid option %s%s (-h will show valid options)\n", 207 opts->program, opt[1] ? "--" : "-", opt); 133 208 return EXIT_FAILURE; 134 209 } 135 210 } 136 211 137 if (args->rfp == NULL && args->cmdline == NULL) { 138 if (*argv == NULL) args->rfp = stdin; 139 else { 140 args->rfp = fopen(argv[0], args->mrbfile ? "rb" : "r"); 212 argc = opts->argc; argv = opts->argv; 213 if (args->cmdline == NULL) { 214 if (*argv == NULL) { 215 if (args->version) exit(EXIT_SUCCESS); 216 args->rfp = stdin; 217 } 218 else { 219 args->rfp = strcmp(argv[0], "-") == 0 ? 220 stdin : fopen(argv[0], args->mrbfile ? "rb" : "r"); 141 221 if (args->rfp == NULL) { 142 printf("%s: Cannot open program file. (%s)\n", *origargv, *argv);222 fprintf(stderr, "%s: Cannot open program file: %s\n", opts->program, argv[0]); 143 223 return EXIT_FAILURE; 144 224 } … … 163 243 mrb_free(mrb, args->cmdline); 164 244 mrb_free(mrb, args->argv); 245 if (args->libc) { 246 while (args->libc--) { 247 mrb_free(mrb, args->libv[args->libc]); 248 } 249 mrb_free(mrb, args->libv); 250 } 165 251 mrb_close(mrb); 166 252 } … … 179 265 180 266 if (mrb == NULL) { 181 fp uts("Invalid mrb_state, exiting mruby\n", stderr);267 fprintf(stderr, "%s: Invalid mrb_state, exiting mruby\n", *argv); 182 268 return EXIT_FAILURE; 183 269 } … … 186 272 if (n == EXIT_FAILURE || (args.cmdline == NULL && args.rfp == NULL)) { 187 273 cleanup(mrb, &args); 188 usage(argv[0]);189 274 return n; 190 275 } … … 200 285 } 201 286 mrb_define_global_const(mrb, "ARGV", ARGV); 287 mrb_gv_set(mrb, mrb_intern_lit(mrb, "$DEBUG"), mrb_bool_value(args.debug)); 202 288 203 289 c = mrbc_context_new(mrb); … … 220 306 } 221 307 308 /* Load libraries */ 309 for (i = 0; i < args.libc; i++) { 310 FILE *lfp = fopen(args.libv[i], args.mrbfile ? "rb" : "r"); 311 if (lfp == NULL) { 312 fprintf(stderr, "%s: Cannot open library file: %s\n", *argv, args.libv[i]); 313 mrbc_context_free(mrb, c); 314 cleanup(mrb, &args); 315 return EXIT_FAILURE; 316 } 317 if (args.mrbfile) { 318 v = mrb_load_irep_file_cxt(mrb, lfp, c); 319 } 320 else { 321 v = mrb_load_file_cxt(mrb, lfp, c); 322 } 323 fclose(lfp); 324 } 325 222 326 /* Load program */ 223 327 if (args.mrbfile) { … … 237 341 mrbc_context_free(mrb, c); 238 342 if (mrb->exc) { 239 if (mrb_undef_p(v)) { 240 mrb_p(mrb, mrb_obj_value(mrb->exc)); 241 } 242 else { 343 if (!mrb_undef_p(v)) { 243 344 mrb_print_error(mrb); 244 345 } 245 n = -1;346 n = EXIT_FAILURE; 246 347 } 247 348 else if (args.check_syntax) { 248 p rintf("Syntax OK\n");349 puts("Syntax OK"); 249 350 } 250 351 } 251 352 cleanup(mrb, &args); 252 353 253 return n == 0 ? EXIT_SUCCESS : EXIT_FAILURE;254 } 354 return n; 355 } -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-strip/bintest/mruby-strip.rb
r321 r439 68 68 `#{cmd('mruby-strip')} -l #{without_lv.path}` 69 69 assert_true without_lv.size < with_lv.size 70 71 assert_equal '[:a, :b]', `#{cmd('mruby')} -b #{with_lv.path}`.chomp72 assert_equal '[]', `#{cmd('mruby')} -b #{without_lv.path}`.chomp70 # 71 # assert_equal '[:a, :b]', `#{cmd('mruby')} -b #{with_lv.path}`.chomp 72 # assert_equal '[]', `#{cmd('mruby')} -b #{without_lv.path}`.chomp 73 73 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c
r331 r439 1 #include <stdio.h> 1 #include <mruby.h> 2 3 #ifdef MRB_DISABLE_STDIO 4 # error mruby-bin-strip conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb' 5 #endif 6 2 7 #include <stdlib.h> 3 8 #include <string.h> 4 #include <mruby.h>5 9 #include <mruby/irep.h> 6 10 #include <mruby/dump.h> … … 12 16 mrb_bool lvar; 13 17 }; 14 15 16 static void17 irep_remove_lv(mrb_state *mrb, mrb_irep *irep)18 {19 size_t i;20 21 if (irep->lv) {22 mrb_free(mrb, irep->lv);23 irep->lv = NULL;24 }25 26 for (i = 0; i < irep->rlen; ++i) {27 irep_remove_lv(mrb, irep->reps[i]);28 }29 }30 18 31 19 static void … … 100 88 /* clear lv if --lvar is enabled */ 101 89 if (args->lvar) { 102 irep_remove_lv(mrb, irep);90 mrb_irep_remove_lv(mrb, irep); 103 91 } 104 92 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-class-ext/src/class.c
r331 r439 6 6 mrb_mod_name(mrb_state *mrb, mrb_value self) 7 7 { 8 mrb_value name = mrb_class_path(mrb, mrb_class_ptr(self)); 9 return mrb_nil_p(name)? name : mrb_str_dup(mrb, name); 8 mrb_value name = mrb_class_path(mrb, mrb_class_ptr(self)); 9 if (mrb_string_p(name)) { 10 MRB_SET_FROZEN_FLAG(mrb_basic_ptr(name)); 11 } 12 return name; 13 } 14 15 static mrb_value 16 mrb_mod_singleton_class_p(mrb_state *mrb, mrb_value self) 17 { 18 return mrb_bool_value(mrb_sclass_p(self)); 19 } 20 21 /* 22 * call-seq: 23 * module_exec(arg...) {|var...| block } -> obj 24 * class_exec(arg...) {|var...| block } -> obj 25 * 26 * Evaluates the given block in the context of the 27 * class/module. The method defined in the block will belong 28 * to the receiver. Any arguments passed to the method will be 29 * passed to the block. This can be used if the block needs to 30 * access instance variables. 31 * 32 * class Thing 33 * end 34 * Thing.class_exec{ 35 * def hello() "Hello there!" end 36 * } 37 * puts Thing.new.hello() 38 */ 39 40 static mrb_value 41 mrb_mod_module_exec(mrb_state *mrb, mrb_value self) 42 { 43 const mrb_value *argv; 44 mrb_int argc; 45 mrb_value blk; 46 47 mrb_get_args(mrb, "*&!", &argv, &argc, &blk); 48 49 mrb->c->ci->target_class = mrb_class_ptr(self); 50 return mrb_yield_cont(mrb, blk, self, argc, argv); 10 51 } 11 52 … … 16 57 17 58 mrb_define_method(mrb, mod, "name", mrb_mod_name, MRB_ARGS_NONE()); 59 mrb_define_method(mrb, mod, "singleton_class?", mrb_mod_singleton_class_p, MRB_ARGS_NONE()); 60 mrb_define_method(mrb, mod, "module_exec", mrb_mod_module_exec, MRB_ARGS_ANY()|MRB_ARGS_BLOCK()); 61 mrb_define_method(mrb, mod, "class_exec", mrb_mod_module_exec, MRB_ARGS_ANY()|MRB_ARGS_BLOCK()); 18 62 } 19 63 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-class-ext/test/module.rb
r331 r439 1 assert 'Module#<' do 2 a = Class.new 3 b = Class.new(a) 4 c = Class.new(a) 5 d = Module.new 6 e = Class.new { include d } 7 f = Module.new { include d } 8 9 # compare class to class 10 assert_true b < a 11 assert_false b < b 12 assert_false a < b 13 assert_nil c < b 14 15 # compare class to module 16 assert_true e < d 17 assert_false d < e 18 assert_nil a < d 19 20 # compare module to module 21 assert_true f < d 22 assert_false f < f 23 assert_false d < f 24 25 assert_raise(TypeError) { a < Object.new } 26 end 27 28 assert 'Module#<=' do 29 a = Class.new 30 b = Class.new(a) 31 c = Class.new(a) 32 d = Module.new 33 e = Class.new { include d } 34 f = Module.new { include d } 35 36 # compare class to class 37 assert_true b <= a 38 assert_true b <= b 39 assert_false a <= b 40 assert_nil c <= b 41 42 # compare class to module 43 assert_true e <= d 44 assert_false d <= e 45 assert_nil a <= d 46 47 # compare module to module 48 assert_true f <= d 49 assert_true f <= f 50 assert_false d <= f 51 52 assert_raise(TypeError) { a <= Object.new } 53 end 54 1 55 assert 'Module#name' do 2 module A 3 class B 56 module Outer 57 class Inner; end 58 const_set :SetInner, Class.new 59 end 60 61 assert_equal 'Outer', Outer.name 62 assert_equal 'Outer::Inner', Outer::Inner.name 63 assert_equal 'Outer::SetInner', Outer::SetInner.name 64 65 outer = Module.new do 66 const_set :SetInner, Class.new 67 end 68 Object.const_set :SetOuter, outer 69 70 assert_equal 'SetOuter', SetOuter.name 71 assert_equal 'SetOuter::SetInner', SetOuter::SetInner.name 72 73 mod = Module.new 74 cls = Class.new 75 76 assert_nil mod.name 77 assert_nil cls.name 78 end 79 80 assert 'Module#singleton_class?' do 81 mod = Module.new 82 cls = Class.new 83 scl = (class <<cls; self; end) 84 85 assert_false mod.singleton_class? 86 assert_false cls.singleton_class? 87 assert_true scl.singleton_class? 88 end 89 90 assert 'Module#module_eval' do 91 mod = Module.new 92 mod.class_exec(1,2,3) do |a,b,c| 93 assert_equal([1,2,3], [a,b,c]) 94 def hi 95 "hi" 4 96 end 5 97 end 6 7 assert_nil A::B.singleton_class.name 8 assert_equal 'Fixnum', Fixnum.name 9 assert_equal 'A::B', A::B.name 98 cls = Class.new 99 cls.class_exec(42) do |x| 100 assert_equal(42, x) 101 include mod 102 def hello 103 "hello" 104 end 105 end 106 obj = cls.new 107 assert_equal("hi", obj.hi) 108 assert_equal("hello", obj.hello) 10 109 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-compiler/core/codegen.c
r331 r439 9 9 #include <stdlib.h> 10 10 #include <string.h> 11 #include <math.h> 11 12 #include <mruby.h> 12 13 #include <mruby/compile.h> … … 24 25 #endif 25 26 27 #define MAXARG_S (1<<16) 28 26 29 typedef mrb_ast_node node; 27 30 typedef struct mrb_parser_state parser_state; … … 37 40 struct loopinfo { 38 41 enum looptype type; 39 int pc 1, pc2, pc3, acc;42 int pc0, pc1, pc2, pc3, acc; 40 43 int ensure_level; 41 44 struct loopinfo *prev; … … 51 54 node *lv; 52 55 53 int sp; 54 int pc; 55 int lastlabel; 56 uint16_t sp; 57 uint16_t pc; 58 uint16_t lastpc; 59 uint16_t lastlabel; 56 60 int ainfo:15; 57 61 mrb_bool mscope:1; … … 59 63 struct loopinfo *loop; 60 64 int ensure_level; 61 char const *filename;65 mrb_sym filename_sym; 62 66 uint16_t lineno; 63 67 64 68 mrb_code *iseq; 65 69 uint16_t *lines; 66 int icapa;70 uint32_t icapa; 67 71 68 72 mrb_irep *irep; 69 size_t pcapa; 70 size_t scapa; 71 size_t rcapa; 73 uint32_t pcapa, scapa, rcapa; 72 74 73 75 uint16_t nlocals; … … 101 103 codegen_scope *tmp = s->prev; 102 104 mrb_free(s->mrb, s->iseq); 105 mrb_free(s->mrb, s->lines); 103 106 mrb_pool_close(s->mpool); 104 107 s = tmp; 105 108 } 106 109 #ifndef MRB_DISABLE_STDIO 107 if (s->filename && s->lineno) { 108 fprintf(stderr, "codegen error:%s:%d: %s\n", s->filename, s->lineno, message); 110 if (s->filename_sym && s->lineno) { 111 const char *filename = mrb_sym_name_len(s->mrb, s->filename_sym, NULL); 112 fprintf(stderr, "codegen error:%s:%d: %s\n", filename, s->lineno, message); 109 113 } 110 114 else { … … 125 129 126 130 static void* 127 codegen_malloc(codegen_scope *s, size_t len)128 {129 void *p = mrb_malloc_simple(s->mrb, len);130 131 if (!p) codegen_error(s, "mrb_malloc");132 return p;133 }134 135 static void*136 131 codegen_realloc(codegen_scope *s, void *p, size_t len) 137 132 { … … 145 140 new_label(codegen_scope *s) 146 141 { 147 s->lastlabel = s->pc; 148 return s->pc; 149 } 150 151 static inline int 152 genop(codegen_scope *s, mrb_code i) 153 { 154 if (s->pc == s->icapa) { 142 return s->lastlabel = s->pc; 143 } 144 145 static void 146 emit_B(codegen_scope *s, uint32_t pc, uint8_t i) 147 { 148 if (pc >= MAXARG_S || s->icapa >= MAXARG_S) { 149 codegen_error(s, "too big code block"); 150 } 151 if (pc >= s->icapa) { 155 152 s->icapa *= 2; 153 if (s->icapa > MAXARG_S) { 154 s->icapa = MAXARG_S; 155 } 156 156 s->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->icapa); 157 157 if (s->lines) { 158 s->lines = (uint16_t*)codegen_realloc(s, s->lines, sizeof(short)*s->icapa); 159 s->irep->lines = s->lines; 160 } 161 } 162 s->iseq[s->pc] = i; 158 s->lines = (uint16_t*)codegen_realloc(s, s->lines, sizeof(uint16_t)*s->icapa); 159 } 160 } 163 161 if (s->lines) { 164 s->lines[s->pc] = s->lineno; 165 } 166 return s->pc++; 162 if (s->lineno > 0 || pc == 0) 163 s->lines[pc] = s->lineno; 164 else 165 s->lines[pc] = s->lines[pc-1]; 166 } 167 s->iseq[pc] = i; 168 } 169 170 static void 171 emit_S(codegen_scope *s, int pc, uint16_t i) 172 { 173 uint8_t hi = i>>8; 174 uint8_t lo = i&0xff; 175 176 emit_B(s, pc, hi); 177 emit_B(s, pc+1, lo); 178 } 179 180 static void 181 gen_B(codegen_scope *s, uint8_t i) 182 { 183 emit_B(s, s->pc, i); 184 s->pc++; 185 } 186 187 static void 188 gen_S(codegen_scope *s, uint16_t i) 189 { 190 emit_S(s, s->pc, i); 191 s->pc += 2; 192 } 193 194 static void 195 genop_0(codegen_scope *s, mrb_code i) 196 { 197 s->lastpc = s->pc; 198 gen_B(s, i); 199 } 200 201 static void 202 genop_1(codegen_scope *s, mrb_code i, uint16_t a) 203 { 204 s->lastpc = s->pc; 205 if (a > 0xff) { 206 gen_B(s, OP_EXT1); 207 gen_B(s, i); 208 gen_S(s, a); 209 } 210 else { 211 gen_B(s, i); 212 gen_B(s, (uint8_t)a); 213 } 214 } 215 216 static void 217 genop_2(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b) 218 { 219 s->lastpc = s->pc; 220 if (a > 0xff && b > 0xff) { 221 gen_B(s, OP_EXT3); 222 gen_B(s, i); 223 gen_S(s, a); 224 gen_S(s, b); 225 } 226 else if (b > 0xff) { 227 gen_B(s, OP_EXT2); 228 gen_B(s, i); 229 gen_B(s, (uint8_t)a); 230 gen_S(s, b); 231 } 232 else if (a > 0xff) { 233 gen_B(s, OP_EXT1); 234 gen_B(s, i); 235 gen_S(s, a); 236 gen_B(s, (uint8_t)b); 237 } 238 else { 239 gen_B(s, i); 240 gen_B(s, (uint8_t)a); 241 gen_B(s, (uint8_t)b); 242 } 243 } 244 245 static void 246 genop_3(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b, uint8_t c) 247 { 248 genop_2(s, i, a, b); 249 gen_B(s, c); 250 } 251 252 static void 253 genop_2S(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b) 254 { 255 genop_1(s, i, a); 256 gen_S(s, b); 257 } 258 259 static void 260 genop_W(codegen_scope *s, mrb_code i, uint32_t a) 261 { 262 uint8_t a1 = (a>>16) & 0xff; 263 uint8_t a2 = (a>>8) & 0xff; 264 uint8_t a3 = a & 0xff; 265 266 s->lastpc = s->pc; 267 gen_B(s, i); 268 gen_B(s, a1); 269 gen_B(s, a2); 270 gen_B(s, a3); 167 271 } 168 272 … … 178 282 } 179 283 180 static int 181 genop_peep(codegen_scope *s, mrb_code i, int val) 182 { 183 /* peephole optimization */ 184 if (!no_optimize(s) && s->lastlabel != s->pc && s->pc > 0) { 185 mrb_code i0 = s->iseq[s->pc-1]; 186 int c1 = GET_OPCODE(i); 187 int c0 = GET_OPCODE(i0); 188 189 switch (c1) { 284 static 285 mrb_bool 286 on_eval(codegen_scope *s) 287 { 288 if (s && s->parser && s->parser->on_eval) 289 return TRUE; 290 return FALSE; 291 } 292 293 struct mrb_insn_data 294 mrb_decode_insn(const mrb_code *pc) 295 { 296 struct mrb_insn_data data = { 0 }; 297 mrb_code insn = READ_B(); 298 uint16_t a = 0; 299 uint16_t b = 0; 300 uint8_t c = 0; 301 302 switch (insn) { 303 #define FETCH_Z() /* empty */ 304 #define OPCODE(i,x) case OP_ ## i: FETCH_ ## x (); break; 305 #include "mruby/ops.h" 306 #undef OPCODE 307 } 308 switch (insn) { 309 case OP_EXT1: 310 insn = READ_B(); 311 switch (insn) { 312 #define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _1 (); break; 313 #include "mruby/ops.h" 314 #undef OPCODE 315 } 316 break; 317 case OP_EXT2: 318 insn = READ_B(); 319 switch (insn) { 320 #define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _2 (); break; 321 #include "mruby/ops.h" 322 #undef OPCODE 323 } 324 break; 325 case OP_EXT3: 326 insn = READ_B(); 327 switch (insn) { 328 #define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _3 (); break; 329 #include "mruby/ops.h" 330 #undef OPCODE 331 } 332 break; 333 default: 334 break; 335 } 336 data.insn = insn; 337 data.a = a; 338 data.b = b; 339 data.c = c; 340 return data; 341 } 342 343 static struct mrb_insn_data 344 mrb_last_insn(codegen_scope *s) 345 { 346 if (s->pc == s->lastpc) { 347 struct mrb_insn_data data; 348 349 data.insn = OP_NOP; 350 return data; 351 } 352 return mrb_decode_insn(&s->iseq[s->lastpc]); 353 } 354 355 static mrb_bool 356 no_peephole(codegen_scope *s) 357 { 358 return no_optimize(s) || s->lastlabel == s->pc || s->pc == 0 || s->pc == s->lastpc; 359 } 360 361 static uint16_t 362 genjmp(codegen_scope *s, mrb_code i, uint16_t pc) 363 { 364 uint16_t pos; 365 366 s->lastpc = s->pc; 367 gen_B(s, i); 368 pos = s->pc; 369 gen_S(s, pc); 370 return pos; 371 } 372 373 static uint16_t 374 genjmp2(codegen_scope *s, mrb_code i, uint16_t a, int pc, int val) 375 { 376 uint16_t pos; 377 378 if (!no_peephole(s) && !val) { 379 struct mrb_insn_data data = mrb_last_insn(s); 380 381 if (data.insn == OP_MOVE && data.a == a) { 382 s->pc = s->lastpc; 383 a = data.b; 384 } 385 } 386 387 s->lastpc = s->pc; 388 if (a > 0xff) { 389 gen_B(s, OP_EXT1); 390 gen_B(s, i); 391 gen_S(s, a); 392 pos = s->pc; 393 gen_S(s, pc); 394 } 395 else { 396 gen_B(s, i); 397 gen_B(s, (uint8_t)a); 398 pos = s->pc; 399 gen_S(s, pc); 400 } 401 return pos; 402 } 403 404 static void 405 gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep) 406 { 407 if (no_peephole(s)) { 408 normal: 409 genop_2(s, OP_MOVE, dst, src); 410 if (on_eval(s)) { 411 genop_0(s, OP_NOP); 412 } 413 return; 414 } 415 else { 416 struct mrb_insn_data data = mrb_last_insn(s); 417 418 switch (data.insn) { 190 419 case OP_MOVE: 191 if (GETARG_A(i) == GETARG_B(i)) { 192 /* skip useless OP_MOVE */ 193 return 0; 194 } 195 if (val) break; 196 switch (c0) { 197 case OP_MOVE: 198 if (GETARG_A(i) == GETARG_A(i0)) { 199 /* skip overriden OP_MOVE */ 200 s->pc--; 201 s->iseq[s->pc] = i; 202 } 203 if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i) == GETARG_B(i0)) { 204 /* skip swapping OP_MOVE */ 205 return 0; 206 } 207 if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { 208 s->pc--; 209 return genop_peep(s, MKOP_AB(OP_MOVE, GETARG_A(i), GETARG_B(i0)), val); 210 } 211 break; 212 case OP_LOADI: 213 if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { 214 s->iseq[s->pc-1] = MKOP_AsBx(OP_LOADI, GETARG_A(i), GETARG_sBx(i0)); 215 return 0; 216 } 217 break; 218 case OP_ARRAY: 219 case OP_HASH: 220 case OP_RANGE: 221 case OP_AREF: 222 case OP_GETUPVAR: 223 if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { 224 s->iseq[s->pc-1] = MKOP_ABC(c0, GETARG_A(i), GETARG_B(i0), GETARG_C(i0)); 225 return 0; 226 } 227 break; 228 case OP_LOADSYM: 229 case OP_GETGLOBAL: 230 case OP_GETIV: 231 case OP_GETCV: 232 case OP_GETCONST: 233 case OP_GETSPECIAL: 234 case OP_LOADL: 235 case OP_STRING: 236 if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { 237 s->iseq[s->pc-1] = MKOP_ABx(c0, GETARG_A(i), GETARG_Bx(i0)); 238 return 0; 239 } 240 break; 241 case OP_SCLASS: 242 if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { 243 s->iseq[s->pc-1] = MKOP_AB(c0, GETARG_A(i), GETARG_B(i0)); 244 return 0; 245 } 246 break; 247 case OP_LOADNIL: 248 case OP_LOADSELF: 249 case OP_LOADT: 250 case OP_LOADF: 251 case OP_OCLASS: 252 if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { 253 s->iseq[s->pc-1] = MKOP_A(c0, GETARG_A(i)); 254 return 0; 255 } 256 break; 257 default: 258 break; 259 } 420 if (dst == src) return; /* remove useless MOVE */ 421 if (data.b == dst && data.a == src) /* skip swapping MOVE */ 422 return; 423 goto normal; 424 case OP_LOADNIL: case OP_LOADSELF: case OP_LOADT: case OP_LOADF: 425 case OP_LOADI__1: 426 case OP_LOADI_0: case OP_LOADI_1: case OP_LOADI_2: case OP_LOADI_3: 427 case OP_LOADI_4: case OP_LOADI_5: case OP_LOADI_6: case OP_LOADI_7: 428 if (nopeep || data.a != src || data.a < s->nlocals) goto normal; 429 s->pc = s->lastpc; 430 genop_1(s, data.insn, dst); 260 431 break; 261 case OP_SETIV: 262 case OP_SETCV: 263 case OP_SETCONST: 264 case OP_SETMCNST: 265 case OP_SETGLOBAL: 266 if (val) break; 267 if (c0 == OP_MOVE) { 268 if (GETARG_A(i) == GETARG_A(i0)) { 269 s->iseq[s->pc-1] = MKOP_ABx(c1, GETARG_B(i0), GETARG_Bx(i)); 270 return 0; 271 } 272 } 273 break; 274 case OP_SETUPVAR: 275 if (val) break; 276 if (c0 == OP_MOVE) { 277 if (GETARG_A(i) == GETARG_A(i0)) { 278 s->iseq[s->pc-1] = MKOP_ABC(c1, GETARG_B(i0), GETARG_B(i), GETARG_C(i)); 279 return 0; 280 } 281 } 282 break; 283 case OP_EPOP: 284 if (c0 == OP_EPOP) { 285 s->iseq[s->pc-1] = MKOP_A(OP_EPOP, GETARG_A(i0)+GETARG_A(i)); 286 return 0; 287 } 288 break; 289 case OP_POPERR: 290 if (c0 == OP_POPERR) { 291 s->iseq[s->pc-1] = MKOP_A(OP_POPERR, GETARG_A(i0)+GETARG_A(i)); 292 return 0; 293 } 294 break; 295 case OP_RETURN: 296 switch (c0) { 297 case OP_RETURN: 298 return 0; 299 case OP_MOVE: 300 if (GETARG_A(i0) >= s->nlocals) { 301 s->iseq[s->pc-1] = MKOP_AB(OP_RETURN, GETARG_B(i0), OP_R_NORMAL); 302 return 0; 303 } 304 break; 305 case OP_SETIV: 306 case OP_SETCV: 307 case OP_SETCONST: 308 case OP_SETMCNST: 309 case OP_SETUPVAR: 310 case OP_SETGLOBAL: 311 s->pc--; 312 genop_peep(s, i0, NOVAL); 313 i0 = s->iseq[s->pc-1]; 314 return genop(s, MKOP_AB(OP_RETURN, GETARG_A(i0), OP_R_NORMAL)); 315 #if 0 316 case OP_SEND: 317 if (GETARG_B(i) == OP_R_NORMAL && GETARG_A(i) == GETARG_A(i0)) { 318 s->iseq[s->pc-1] = MKOP_ABC(OP_TAILCALL, GETARG_A(i0), GETARG_B(i0), GETARG_C(i0)); 319 return; 320 } 321 break; 322 #endif 323 default: 324 break; 325 } 326 break; 327 case OP_ADD: 328 case OP_SUB: 329 if (c0 == OP_LOADI) { 330 int c = GETARG_sBx(i0); 331 332 if (c1 == OP_SUB) c = -c; 333 if (c > 127 || c < -127) break; 334 if (0 <= c) 335 s->iseq[s->pc-1] = MKOP_ABC(OP_ADDI, GETARG_A(i), GETARG_B(i), c); 336 else 337 s->iseq[s->pc-1] = MKOP_ABC(OP_SUBI, GETARG_A(i), GETARG_B(i), -c); 338 return 0; 339 } 340 case OP_STRCAT: 341 if (c0 == OP_STRING) { 342 mrb_value v = s->irep->pool[GETARG_Bx(i0)]; 343 344 if (mrb_string_p(v) && RSTRING_LEN(v) == 0) { 345 s->pc--; 346 return 0; 347 } 348 } 349 if (c0 == OP_LOADNIL) { 350 if (GETARG_B(i) == GETARG_A(i0)) { 351 s->pc--; 352 return 0; 353 } 354 } 355 break; 356 case OP_JMPIF: 357 case OP_JMPNOT: 358 if (c0 == OP_MOVE && GETARG_A(i) == GETARG_A(i0)) { 359 s->iseq[s->pc-1] = MKOP_AsBx(c1, GETARG_B(i0), GETARG_sBx(i)); 360 return s->pc-1; 361 } 432 case OP_LOADI: case OP_LOADINEG: case OP_LOADL: case OP_LOADSYM: 433 case OP_GETGV: case OP_GETSV: case OP_GETIV: case OP_GETCV: 434 case OP_GETCONST: case OP_STRING: 435 case OP_LAMBDA: case OP_BLOCK: case OP_METHOD: case OP_BLKPUSH: 436 if (nopeep || data.a != src || data.a < s->nlocals) goto normal; 437 s->pc = s->lastpc; 438 genop_2(s, data.insn, dst, data.b); 362 439 break; 363 440 default: 441 goto normal; 442 } 443 } 444 } 445 446 static void 447 gen_return(codegen_scope *s, uint8_t op, uint16_t src) 448 { 449 if (no_peephole(s)) { 450 genop_1(s, op, src); 451 } 452 else { 453 struct mrb_insn_data data = mrb_last_insn(s); 454 455 if (data.insn == OP_MOVE && src == data.a) { 456 s->pc = s->lastpc; 457 genop_1(s, op, data.b); 458 } 459 else if (data.insn != OP_RETURN) { 460 genop_1(s, op, src); 461 } 462 } 463 } 464 465 static void 466 gen_addsub(codegen_scope *s, uint8_t op, uint16_t dst) 467 { 468 if (no_peephole(s)) { 469 normal: 470 genop_1(s, op, dst); 471 return; 472 } 473 else { 474 struct mrb_insn_data data = mrb_last_insn(s); 475 476 switch (data.insn) { 477 case OP_LOADI__1: 478 if (op == OP_ADD) op = OP_SUB; 479 else op = OP_ADD; 480 data.b = 1; 481 goto replace; 482 case OP_LOADI_0: case OP_LOADI_1: case OP_LOADI_2: case OP_LOADI_3: 483 case OP_LOADI_4: case OP_LOADI_5: case OP_LOADI_6: case OP_LOADI_7: 484 data.b = data.insn - OP_LOADI_0; 485 /* fall through */ 486 case OP_LOADI: 487 replace: 488 if (data.b >= 128) goto normal; 489 s->pc = s->lastpc; 490 if (op == OP_ADD) { 491 genop_2(s, OP_ADDI, dst, (uint8_t)data.b); 492 } 493 else { 494 genop_2(s, OP_SUBI, dst, (uint8_t)data.b); 495 } 364 496 break; 365 } 366 } 367 return genop(s, i); 497 default: 498 goto normal; 499 } 500 } 501 } 502 503 static int 504 dispatch(codegen_scope *s, uint16_t pos0) 505 { 506 uint16_t newpos; 507 508 s->lastlabel = s->pc; 509 newpos = PEEK_S(s->iseq+pos0); 510 emit_S(s, pos0, s->pc); 511 return newpos; 368 512 } 369 513 370 514 static void 371 scope_error(codegen_scope *s) 372 { 373 exit(EXIT_FAILURE); 374 } 375 376 static inline void 377 dispatch(codegen_scope *s, int pc) 378 { 379 int diff = s->pc - pc; 380 mrb_code i = s->iseq[pc]; 381 int c = GET_OPCODE(i); 382 383 s->lastlabel = s->pc; 384 switch (c) { 385 case OP_JMP: 386 case OP_JMPIF: 387 case OP_JMPNOT: 388 case OP_ONERR: 389 break; 390 default: 391 #ifndef MRB_DISABLE_STDIO 392 fprintf(stderr, "bug: dispatch on non JMP op\n"); 393 #endif 394 scope_error(s); 395 break; 396 } 397 if (diff > MAXARG_sBx) { 398 codegen_error(s, "too distant jump address"); 399 } 400 s->iseq[pc] = MKOP_AsBx(c, GETARG_A(i), diff); 401 } 402 403 static void 404 dispatch_linked(codegen_scope *s, int pc) 405 { 406 mrb_code i; 407 int pos; 408 409 if (!pc) return; 515 dispatch_linked(codegen_scope *s, uint16_t pos) 516 { 517 if (pos==0) return; 410 518 for (;;) { 411 i = s->iseq[pc]; 412 pos = GETARG_sBx(i); 413 dispatch(s, pc); 414 if (!pos) break; 415 pc = pos; 519 pos = dispatch(s, pos); 520 if (pos==0) break; 416 521 } 417 522 } … … 419 524 #define nregs_update do {if (s->sp > s->nregs) s->nregs = s->sp;} while (0) 420 525 static void 421 push_(codegen_scope *s) 422 { 423 if (s->sp > 511) { 424 codegen_error(s, "too complex expression"); 425 } 426 s->sp++; 427 nregs_update; 428 } 429 430 static void 431 push_n_(codegen_scope *s, size_t n) 432 { 433 if (s->sp+n > 511) { 526 push_n_(codegen_scope *s, int n) 527 { 528 if (s->sp+n >= 0xffff) { 434 529 codegen_error(s, "too complex expression"); 435 530 } … … 438 533 } 439 534 440 #define push() push_(s) 535 static void 536 pop_n_(codegen_scope *s, int n) 537 { 538 if ((int)s->sp-n < 0) { 539 codegen_error(s, "stack pointer underflow"); 540 } 541 s->sp-=n; 542 } 543 544 #define push() push_n_(s,1) 441 545 #define push_n(n) push_n_(s,n) 442 #define pop_(s) ((s)->sp--) 443 #define pop() pop_(s) 444 #define pop_n(n) (s->sp-=(n)) 546 #define pop() pop_n_(s,1) 547 #define pop_n(n) pop_n_(s,n) 445 548 #define cursp() (s->sp) 446 549 … … 448 551 new_lit(codegen_scope *s, mrb_value val) 449 552 { 450 size_t i;553 int i; 451 554 mrb_value *pv; 452 555 … … 457 560 pv = &s->irep->pool[i]; 458 561 459 if ( mrb_type(*pv) != MRB_TT_STRING) continue;562 if (!mrb_string_p(*pv)) continue; 460 563 if ((len = RSTRING_LEN(*pv)) != RSTRING_LEN(val)) continue; 461 564 if (memcmp(RSTRING_PTR(*pv), RSTRING_PTR(val), len) == 0) … … 463 566 } 464 567 break; 568 #ifndef MRB_WITHOUT_FLOAT 465 569 case MRB_TT_FLOAT: 466 570 for (i=0; i<s->irep->plen; i++) { 571 mrb_float f1, f2; 467 572 pv = &s->irep->pool[i]; 468 if (mrb_type(*pv) != MRB_TT_FLOAT) continue; 469 if (mrb_float(*pv) == mrb_float(val)) return i; 470 } 471 break; 573 if (!mrb_float_p(*pv)) continue; 574 f1 = mrb_float(*pv); 575 f2 = mrb_float(val); 576 if (f1 == f2 && !signbit(f1) == !signbit(f2)) return i; 577 } 578 break; 579 #endif 472 580 case MRB_TT_FIXNUM: 473 581 for (i=0; i<s->irep->plen; i++) { … … 492 600 switch (mrb_type(val)) { 493 601 case MRB_TT_STRING: 494 *pv = mrb_str_pool(s->mrb, val); 495 break; 496 602 *pv = mrb_str_pool(s->mrb, RSTRING_PTR(val), RSTRING_LEN(val), RSTR_NOFREE_P(RSTRING(val))); 603 break; 604 605 #ifndef MRB_WITHOUT_FLOAT 497 606 case MRB_TT_FLOAT: 498 607 #ifdef MRB_WORD_BOXING … … 500 609 break; 501 610 #endif 611 #endif 502 612 case MRB_TT_FIXNUM: 503 613 *pv = val; … … 511 621 } 512 622 513 /* method symbols should be fit in 9 bits */514 #define MAXMSYMLEN 512515 623 /* maximum symbol numbers */ 516 #define MAXSYMLEN 65536624 #define MAXSYMLEN 0x10000 517 625 518 626 static int 519 new_ msym(codegen_scope *s, mrb_sym sym)520 { 521 size_t i, len;627 new_sym(codegen_scope *s, mrb_sym sym) 628 { 629 int i, len; 522 630 523 631 mrb_assert(s->irep); 524 632 525 633 len = s->irep->slen; 526 if (len > MAXMSYMLEN) len = MAXMSYMLEN;527 634 for (i=0; i<len; i++) { 528 635 if (s->irep->syms[i] == sym) return i; 529 if (s->irep->syms[i] == 0) break; 530 } 531 if (i == MAXMSYMLEN) { 532 codegen_error(s, "too many symbols (max " MRB_STRINGIZE(MAXMSYMLEN) ")"); 533 } 534 s->irep->syms[i] = sym; 535 if (i == s->irep->slen) s->irep->slen++; 536 return i; 537 } 538 539 static int 540 new_sym(codegen_scope *s, mrb_sym sym) 541 { 542 size_t i; 543 544 for (i=0; i<s->irep->slen; i++) { 545 if (s->irep->syms[i] == sym) return i; 546 } 547 if (s->irep->slen == MAXSYMLEN) { 548 codegen_error(s, "too many symbols (max " MRB_STRINGIZE(MAXSYMLEN) ")"); 549 } 550 551 if (s->irep->slen > MAXMSYMLEN/2 && s->scapa == MAXMSYMLEN) { 552 s->scapa = MAXSYMLEN; 553 s->irep->syms = (mrb_sym *)codegen_realloc(s, s->irep->syms, sizeof(mrb_sym)*MAXSYMLEN); 554 for (i = s->irep->slen; i < MAXMSYMLEN; i++) { 555 static const mrb_sym mrb_sym_zero = { 0 }; 556 s->irep->syms[i] = mrb_sym_zero; 557 } 558 s->irep->slen = MAXMSYMLEN; 636 } 637 if (s->irep->slen >= s->scapa) { 638 s->scapa *= 2; 639 s->irep->syms = (mrb_sym*)codegen_realloc(s, s->irep->syms, sizeof(mrb_sym)*s->scapa); 559 640 } 560 641 s->irep->syms[s->irep->slen] = sym; … … 574 655 } 575 656 576 #define sym(x) ((mrb_sym)(intptr_t)(x)) 577 #define lv_name(lv) sym((lv)->car) 657 #define nint(x) ((int)(intptr_t)(x)) 658 #define nchar(x) ((char)(intptr_t)(x)) 659 #define nsym(x) ((mrb_sym)(intptr_t)(x)) 660 661 #define lv_name(lv) nsym((lv)->car) 662 578 663 static int 579 664 lv_idx(codegen_scope *s, mrb_sym id) … … 597 682 struct loopinfo *lp; 598 683 node *n2; 599 mrb_code c;600 684 601 685 /* generate receiver */ … … 603 687 /* generate loop-block */ 604 688 s = scope_new(s->mrb, s, NULL); 605 if (s == NULL) {606 raise_error(prev, "unexpected scope");607 }608 689 609 690 push(); /* push for a block parameter */ … … 611 692 /* generate loop variable */ 612 693 n2 = tree->car; 613 genop (s, MKOP_Ax(OP_ENTER, 0x40000));694 genop_W(s, OP_ENTER, 0x40000); 614 695 if (n2->car && !n2->car->cdr && !n2->cdr) { 615 696 gen_assignment(s, n2->car->car, 1, NOVAL); … … 625 706 codegen(s, tree->cdr->cdr->car, VAL); 626 707 pop(); 627 if (s->pc > 0) { 628 c = s->iseq[s->pc-1]; 629 if (GET_OPCODE(c) != OP_RETURN || GETARG_B(c) != OP_R_NORMAL || s->pc == s->lastlabel) 630 genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL); 631 } 708 gen_return(s, OP_RETURN, cursp()); 632 709 loop_pop(s, NOVAL); 633 710 scope_finish(s); 634 711 s = prev; 635 genop(s, MKOP_Abc(OP_LAMBDA, cursp(), s->irep->rlen-1, OP_L_BLOCK)); 712 genop_2(s, OP_BLOCK, cursp(), s->irep->rlen-1); 713 push();pop(); /* space for a block */ 636 714 pop(); 637 idx = new_ msym(s, mrb_intern_lit(s->mrb, "each"));638 genop (s, MKOP_ABC(OP_SENDB, cursp(), idx, 0));715 idx = new_sym(s, mrb_intern_lit(s->mrb, "each")); 716 genop_3(s, OP_SENDB, cursp(), idx, 0); 639 717 } 640 718 … … 642 720 lambda_body(codegen_scope *s, node *tree, int blk) 643 721 { 644 mrb_code c;645 722 codegen_scope *parent = s; 646 723 s = scope_new(s->mrb, s, tree->car); 647 if (s == NULL) {648 raise_error(parent, "unexpected scope");649 }650 724 651 725 s->mscope = !blk; … … 653 727 if (blk) { 654 728 struct loopinfo *lp = loop_push(s, LOOP_BLOCK); 655 lp->pc 1= new_label(s);729 lp->pc0 = new_label(s); 656 730 } 657 731 tree = tree->cdr; 658 if (tree->car) { 732 if (tree->car == NULL) { 733 genop_W(s, OP_ENTER, 0); 734 } 735 else { 659 736 mrb_aspec a; 660 737 int ma, oa, ra, pa, ka, kd, ba; 661 738 int pos, i; 662 node *n, *opt; 663 739 node *opt; 740 node *margs, *pargs; 741 node *tail; 742 743 /* mandatory arguments */ 664 744 ma = node_len(tree->car->car); 665 n= tree->car->car;666 while (n) {667 n = n->cdr; 668 }745 margs = tree->car->car; 746 tail = tree->car->cdr->cdr->cdr->cdr; 747 748 /* optional arguments */ 669 749 oa = node_len(tree->car->cdr->car); 750 /* rest argument? */ 670 751 ra = tree->car->cdr->cdr->car ? 1 : 0; 752 /* mandatory arugments after rest argument */ 671 753 pa = node_len(tree->car->cdr->cdr->cdr->car); 672 ka = kd = 0; 673 ba = tree->car->cdr->cdr->cdr->cdr ? 1 : 0; 754 pargs = tree->car->cdr->cdr->cdr->car; 755 /* keyword arguments */ 756 ka = tail? node_len(tail->cdr->car) : 0; 757 /* keyword dictionary? */ 758 kd = tail && tail->cdr->cdr->car? 1 : 0; 759 /* block argument? */ 760 ba = tail && tail->cdr->cdr->cdr->car ? 1 : 0; 674 761 675 762 if (ma > 0x1f || oa > 0x1f || pa > 0x1f || ka > 0x1f) { 676 763 codegen_error(s, "too many formal arguments"); 677 764 } 678 a = ((mrb_aspec)(ma & 0x1f) << 18) 679 | ((mrb_aspec)(oa & 0x1f) << 13) 680 | ((ra & 1) << 12) 681 | ((pa & 0x1f) << 7) 682 | ((ka & 0x1f) << 2) 683 | ((kd & 1)<< 1) 684 | (ba & 1); 685 s->ainfo = (((ma+oa) & 0x3f) << 6) /* (12bits = 6:1:5) */ 686 | ((ra & 1) << 5) 687 | (pa & 0x1f); 688 genop(s, MKOP_Ax(OP_ENTER, a)); 765 a = MRB_ARGS_REQ(ma) 766 | MRB_ARGS_OPT(oa) 767 | (ra? MRB_ARGS_REST() : 0) 768 | MRB_ARGS_POST(pa) 769 | MRB_ARGS_KEY(ka, kd) 770 | (ba? MRB_ARGS_BLOCK() : 0); 771 s->ainfo = (((ma+oa) & 0x3f) << 7) /* (12bits = 5:1:5:1) */ 772 | ((ra & 0x1) << 6) 773 | ((pa & 0x1f) << 1) 774 | ((ka | kd) != 0 ? 0x01 : 0x00); 775 genop_W(s, OP_ENTER, a); 776 /* generate jump table for optional arguments initializer */ 689 777 pos = new_label(s); 690 778 for (i=0; i<oa; i++) { 691 779 new_label(s); 692 gen op(s, MKOP_sBx(OP_JMP, 0));780 genjmp(s, OP_JMP, 0); 693 781 } 694 782 if (oa > 0) { 695 gen op(s, MKOP_sBx(OP_JMP, 0));783 genjmp(s, OP_JMP, 0); 696 784 } 697 785 opt = tree->car->cdr->car; … … 700 788 int idx; 701 789 702 dispatch(s, pos+i );790 dispatch(s, pos+i*3+1); 703 791 codegen(s, opt->car->cdr, VAL); 704 idx = lv_idx(s, (mrb_sym)(intptr_t)opt->car->car);705 792 pop(); 706 genop_peep(s, MKOP_AB(OP_MOVE, idx, cursp()), NOVAL); 793 idx = lv_idx(s, nsym(opt->car->car)); 794 gen_move(s, idx, cursp(), 0); 707 795 i++; 708 796 opt = opt->cdr; 709 797 } 710 798 if (oa > 0) { 711 dispatch(s, pos+i); 712 } 713 } 799 dispatch(s, pos+i*3+1); 800 } 801 802 /* keyword arguments */ 803 if (tail) { 804 node *kwds = tail->cdr->car; 805 int kwrest = 0; 806 807 if (tail->cdr->cdr->car) { 808 kwrest = 1; 809 } 810 mrb_assert(nint(tail->car) == NODE_ARGS_TAIL); 811 mrb_assert(node_len(tail) == 4); 812 813 while (kwds) { 814 int jmpif_key_p, jmp_def_set = -1; 815 node *kwd = kwds->car, *def_arg = kwd->cdr->cdr->car; 816 mrb_sym kwd_sym = nsym(kwd->cdr->car); 817 818 mrb_assert(nint(kwd->car) == NODE_KW_ARG); 819 820 if (def_arg) { 821 genop_2(s, OP_KEY_P, lv_idx(s, kwd_sym), new_sym(s, kwd_sym)); 822 jmpif_key_p = genjmp2(s, OP_JMPIF, lv_idx(s, kwd_sym), 0, 0); 823 codegen(s, def_arg, VAL); 824 pop(); 825 gen_move(s, lv_idx(s, kwd_sym), cursp(), 0); 826 jmp_def_set = genjmp(s, OP_JMP, 0); 827 dispatch(s, jmpif_key_p); 828 } 829 genop_2(s, OP_KARG, lv_idx(s, kwd_sym), new_sym(s, kwd_sym)); 830 if (jmp_def_set != -1) { 831 dispatch(s, jmp_def_set); 832 } 833 i++; 834 835 kwds = kwds->cdr; 836 } 837 if (tail->cdr->car && !kwrest) { 838 genop_0(s, OP_KEYEND); 839 } 840 } 841 842 /* argument destructuring */ 843 if (margs) { 844 node *n = margs; 845 846 pos = 1; 847 while (n) { 848 if (nint(n->car->car) == NODE_MASGN) { 849 gen_vmassignment(s, n->car->cdr->car, pos, NOVAL); 850 } 851 pos++; 852 n = n->cdr; 853 } 854 } 855 if (pargs) { 856 node *n = margs; 857 858 pos = ma+oa+ra+1; 859 while (n) { 860 if (nint(n->car->car) == NODE_MASGN) { 861 gen_vmassignment(s, n->car->cdr->car, pos, NOVAL); 862 } 863 pos++; 864 n = n->cdr; 865 } 866 } 867 } 868 714 869 codegen(s, tree->cdr->car, VAL); 715 870 pop(); 716 871 if (s->pc > 0) { 717 c = s->iseq[s->pc-1]; 718 if (GET_OPCODE(c) != OP_RETURN || GETARG_B(c) != OP_R_NORMAL || s->pc == s->lastlabel) { 719 if (s->nregs == 0) { 720 genop(s, MKOP_A(OP_LOADNIL, 0)); 721 genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); 722 } 723 else { 724 genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL); 725 } 726 } 872 gen_return(s, OP_RETURN, cursp()); 727 873 } 728 874 if (blk) { … … 737 883 { 738 884 codegen_scope *scope = scope_new(s->mrb, s, tree->car); 739 if (scope == NULL) {740 raise_error(s, "unexpected scope");741 }742 885 743 886 codegen(scope, tree->cdr, VAL); 887 gen_return(scope, OP_RETURN, scope->sp-1); 744 888 if (!s->iseq) { 745 genop(scope, MKOP_A(OP_STOP, 0)); 746 } 747 else if (!val) { 748 genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); 749 } 750 else { 751 if (scope->nregs == 0) { 752 genop(scope, MKOP_A(OP_LOADNIL, 0)); 753 genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); 754 } 755 else { 756 genop_peep(scope, MKOP_AB(OP_RETURN, scope->sp-1, OP_R_NORMAL), NOVAL); 757 } 889 genop_0(scope, OP_STOP); 758 890 } 759 891 scope_finish(scope); … … 769 901 { 770 902 while (t) { 771 if ( (intptr_t)t->car->car== NODE_SPLAT) return FALSE;903 if (nint(t->car->car) == NODE_SPLAT) return FALSE; 772 904 t = t->cdr; 773 905 } … … 782 914 char *name2; 783 915 784 name = mrb_sym 2name_len(s->mrb, a, &len);916 name = mrb_sym_name_len(s->mrb, a, &len); 785 917 name2 = (char *)codegen_palloc(s, 786 918 (size_t)len … … 805 937 806 938 while (t) { 807 is_splat = (intptr_t)t->car->car== NODE_SPLAT; /* splat mode */939 is_splat = nint(t->car->car) == NODE_SPLAT; /* splat mode */ 808 940 if ( 809 941 n+extra >= CALL_MAXARGS - 1 /* need to subtract one because vm.c expects an array if n == CALL_MAXARGS */ 810 942 || is_splat) { 811 943 if (val) { 812 if (is_splat && n == 0 && (intptr_t)t->car->cdr->car== NODE_ARRAY) {944 if (is_splat && n == 0 && nint(t->car->cdr->car) == NODE_ARRAY) { 813 945 codegen(s, t->car->cdr, VAL); 814 946 pop(); … … 816 948 else { 817 949 pop_n(n); 818 genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n)); 950 if (n == 0 && is_splat) { 951 genop_1(s, OP_LOADNIL, cursp()); 952 } 953 else { 954 genop_2(s, OP_ARRAY, cursp(), n); 955 } 819 956 push(); 820 957 codegen(s, t->car, VAL); 821 958 pop(); pop(); 822 959 if (is_splat) { 823 genop (s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));960 genop_1(s, OP_ARYCAT, cursp()); 824 961 } 825 962 else { 826 genop (s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));963 genop_1(s, OP_ARYPUSH, cursp()); 827 964 } 828 965 } … … 832 969 codegen(s, t->car, VAL); 833 970 pop(); pop(); 834 if ( (intptr_t)t->car->car== NODE_SPLAT) {835 genop (s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));971 if (nint(t->car->car) == NODE_SPLAT) { 972 genop_1(s, OP_ARYCAT, cursp()); 836 973 } 837 974 else { 838 genop (s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));975 genop_1(s, OP_ARYPUSH, cursp()); 839 976 } 840 977 t = t->cdr; … … 860 997 gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) 861 998 { 862 mrb_sym sym = name ? name : sym(tree->cdr->car);863 int idx,skip = 0;999 mrb_sym sym = name ? name : nsym(tree->cdr->car); 1000 int skip = 0; 864 1001 int n = 0, noop = 0, sendv = 0, blk = 0; 865 1002 … … 867 1004 if (safe) { 868 1005 int recv = cursp()-1; 869 genop(s, MKOP_A(OP_LOADNIL, cursp())); 870 push(); 871 genop(s, MKOP_AB(OP_MOVE, cursp(), recv)); 872 push(); pop(); /* space for a block */ 873 pop(); 874 idx = new_msym(s, mrb_intern_lit(s->mrb, "==")); 875 genop(s, MKOP_ABC(OP_EQ, cursp(), idx, 1)); 876 skip = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), 0)); 877 } 878 idx = new_msym(s, sym); 1006 gen_move(s, cursp(), recv, 1); 1007 skip = genjmp2(s, OP_JMPNIL, cursp(), 0, val); 1008 } 879 1009 tree = tree->cdr->cdr->car; 880 1010 if (tree) { … … 885 1015 } 886 1016 } 887 if (sp) { 1017 if (sp) { /* last argument pushed (attr=) */ 888 1018 if (sendv) { 1019 gen_move(s, cursp(), sp, 0); 889 1020 pop(); 890 genop (s, MKOP_AB(OP_ARYPUSH, cursp(), sp));1021 genop_1(s, OP_ARYPUSH, cursp()); 891 1022 push(); 892 1023 } 893 1024 else { 894 gen op(s, MKOP_AB(OP_MOVE, cursp(), sp));1025 gen_move(s, cursp(), sp, 0); 895 1026 push(); 896 1027 n++; … … 901 1032 codegen(s, tree->cdr, VAL); 902 1033 pop(); 903 } 904 else { 905 blk = cursp(); 1034 blk = 1; 906 1035 } 907 1036 push();pop(); … … 909 1038 { 910 1039 mrb_int symlen; 911 const char *symname = mrb_sym 2name_len(s->mrb, sym, &symlen);1040 const char *symname = mrb_sym_name_len(s->mrb, sym, &symlen); 912 1041 913 1042 if (!noop && symlen == 1 && symname[0] == '+' && n == 1) { 914 gen op_peep(s, MKOP_ABC(OP_ADD, cursp(), idx, n), val);1043 gen_addsub(s, OP_ADD, cursp()); 915 1044 } 916 1045 else if (!noop && symlen == 1 && symname[0] == '-' && n == 1) { 917 gen op_peep(s, MKOP_ABC(OP_SUB, cursp(), idx, n), val);1046 gen_addsub(s, OP_SUB, cursp()); 918 1047 } 919 1048 else if (!noop && symlen == 1 && symname[0] == '*' && n == 1) { 920 genop (s, MKOP_ABC(OP_MUL, cursp(), idx, n));1049 genop_1(s, OP_MUL, cursp()); 921 1050 } 922 1051 else if (!noop && symlen == 1 && symname[0] == '/' && n == 1) { 923 genop (s, MKOP_ABC(OP_DIV, cursp(), idx, n));1052 genop_1(s, OP_DIV, cursp()); 924 1053 } 925 1054 else if (!noop && symlen == 1 && symname[0] == '<' && n == 1) { 926 genop (s, MKOP_ABC(OP_LT, cursp(), idx, n));1055 genop_1(s, OP_LT, cursp()); 927 1056 } 928 1057 else if (!noop && symlen == 2 && symname[0] == '<' && symname[1] == '=' && n == 1) { 929 genop (s, MKOP_ABC(OP_LE, cursp(), idx, n));1058 genop_1(s, OP_LE, cursp()); 930 1059 } 931 1060 else if (!noop && symlen == 1 && symname[0] == '>' && n == 1) { 932 genop (s, MKOP_ABC(OP_GT, cursp(), idx, n));1061 genop_1(s, OP_GT, cursp()); 933 1062 } 934 1063 else if (!noop && symlen == 2 && symname[0] == '>' && symname[1] == '=' && n == 1) { 935 genop (s, MKOP_ABC(OP_GE, cursp(), idx, n));1064 genop_1(s, OP_GE, cursp()); 936 1065 } 937 1066 else if (!noop && symlen == 2 && symname[0] == '=' && symname[1] == '=' && n == 1) { 938 genop (s, MKOP_ABC(OP_EQ, cursp(), idx, n));1067 genop_1(s, OP_EQ, cursp()); 939 1068 } 940 1069 else { 941 if (sendv) n = CALL_MAXARGS; 942 if (blk > 0) { /* no block */ 943 genop(s, MKOP_ABC(OP_SEND, cursp(), idx, n)); 1070 int idx = new_sym(s, sym); 1071 1072 if (sendv) { 1073 genop_2(s, blk ? OP_SENDVB : OP_SENDV, cursp(), idx); 944 1074 } 945 1075 else { 946 genop (s, MKOP_ABC(OP_SENDB, cursp(), idx, n));1076 genop_3(s, blk ? OP_SENDB : OP_SEND, cursp(), idx, n); 947 1077 } 948 1078 } … … 960 1090 { 961 1091 int idx; 962 int type = (intptr_t)tree->car;1092 int type = nint(tree->car); 963 1093 964 1094 tree = tree->cdr; 965 1095 switch (type) { 966 1096 case NODE_GVAR: 967 idx = new_sym(s, sym(tree)); 968 genop_peep(s, MKOP_ABx(OP_SETGLOBAL, sp, idx), val); 969 break; 1097 idx = new_sym(s, nsym(tree)); 1098 genop_2(s, OP_SETGV, sp, idx); 1099 break; 1100 case NODE_ARG: 970 1101 case NODE_LVAR: 971 idx = lv_idx(s, sym(tree));1102 idx = lv_idx(s, nsym(tree)); 972 1103 if (idx > 0) { 973 1104 if (idx != sp) { 974 genop_peep(s, MKOP_AB(OP_MOVE, idx, sp), val); 1105 gen_move(s, idx, sp, val); 1106 if (val && on_eval(s)) genop_0(s, OP_NOP); 975 1107 } 976 1108 break; … … 981 1113 982 1114 while (up) { 983 idx = lv_idx(up, sym(tree));1115 idx = lv_idx(up, nsym(tree)); 984 1116 if (idx > 0) { 985 genop_ peep(s, MKOP_ABC(OP_SETUPVAR, sp, idx, lv), val);1117 genop_3(s, OP_SETUPVAR, sp, idx, lv); 986 1118 break; 987 1119 } … … 991 1123 } 992 1124 break; 1125 case NODE_NVAR: 1126 idx = nint(tree); 1127 codegen_error(s, "Can't assign to numbered parameter"); 1128 break; 993 1129 case NODE_IVAR: 994 idx = new_sym(s, sym(tree));995 genop_ peep(s, MKOP_ABx(OP_SETIV, sp, idx), val);1130 idx = new_sym(s, nsym(tree)); 1131 genop_2(s, OP_SETIV, sp, idx); 996 1132 break; 997 1133 case NODE_CVAR: 998 idx = new_sym(s, sym(tree));999 genop_ peep(s, MKOP_ABx(OP_SETCV, sp, idx), val);1134 idx = new_sym(s, nsym(tree)); 1135 genop_2(s, OP_SETCV, sp, idx); 1000 1136 break; 1001 1137 case NODE_CONST: 1002 idx = new_sym(s, sym(tree));1003 genop_ peep(s, MKOP_ABx(OP_SETCONST, sp, idx), val);1138 idx = new_sym(s, nsym(tree)); 1139 genop_2(s, OP_SETCONST, sp, idx); 1004 1140 break; 1005 1141 case NODE_COLON2: 1006 idx = new_sym(s, sym(tree->cdr)); 1007 genop_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), NOVAL); 1142 gen_move(s, cursp(), sp, 0); 1008 1143 push(); 1009 1144 codegen(s, tree->car, VAL); 1010 1145 pop_n(2); 1011 genop_peep(s, MKOP_ABx(OP_SETMCNST, cursp(), idx), val); 1146 idx = new_sym(s, nsym(tree->cdr)); 1147 genop_2(s, OP_SETMCNST, sp, idx); 1012 1148 break; 1013 1149 … … 1015 1151 case NODE_SCALL: 1016 1152 push(); 1017 gen_call(s, tree, attrsym(s, sym(tree->cdr->car)), sp, NOVAL,1153 gen_call(s, tree, attrsym(s, nsym(tree->cdr->car)), sp, NOVAL, 1018 1154 type == NODE_SCALL); 1019 1155 pop(); 1020 1156 if (val) { 1021 gen op_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), val);1157 gen_move(s, cursp(), sp, 0); 1022 1158 } 1023 1159 break; … … 1050 1186 n = 0; 1051 1187 while (t) { 1052 genop(s, MKOP_ABC(OP_AREF, cursp(), rhs, n)); 1053 gen_assignment(s, t->car, cursp(), NOVAL); 1188 int sp = cursp(); 1189 1190 genop_3(s, OP_AREF, sp, rhs, n); 1191 push(); 1192 gen_assignment(s, t->car, sp, NOVAL); 1193 pop(); 1054 1194 n++; 1055 1195 t = t->cdr; … … 1065 1205 } 1066 1206 } 1067 if (val) { 1068 genop(s, MKOP_AB(OP_MOVE, cursp(), rhs)); 1069 } 1070 else { 1071 pop(); 1072 } 1073 push_n(post); 1074 pop_n(post); 1075 genop(s, MKOP_ABC(OP_APOST, cursp(), n, post)); 1207 gen_move(s, cursp(), rhs, val); 1208 push_n(post+1); 1209 pop_n(post+1); 1210 genop_3(s, OP_APOST, cursp(), n, post); 1076 1211 n = 1; 1077 if (t->car ) {/* rest */1212 if (t->car && t->car != (node*)-1) { /* rest */ 1078 1213 gen_assignment(s, t->car, cursp(), NOVAL); 1079 1214 } … … 1086 1221 } 1087 1222 } 1088 if ( !val) {1089 push();1223 if (val) { 1224 gen_move(s, cursp(), rhs, 0); 1090 1225 } 1091 1226 } … … 1093 1228 1094 1229 static void 1095 gen_ send_intern(codegen_scope *s)1230 gen_intern(codegen_scope *s) 1096 1231 { 1097 1232 pop(); 1098 genop (s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "intern")), 0));1233 genop_1(s, OP_INTERN, cursp()); 1099 1234 push(); 1100 1235 } 1236 1101 1237 static void 1102 1238 gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) … … 1106 1242 1107 1243 while (tree) { 1108 switch ( (intptr_t)tree->car->car) {1244 switch (nint(tree->car->car)) { 1109 1245 case NODE_STR: 1110 if ((tree->cdr == NULL) && ( (intptr_t)tree->car->cdr->cdr== 0))1246 if ((tree->cdr == NULL) && (nint(tree->car->cdr->cdr) == 0)) 1111 1247 break; 1112 1248 /* fall through */ … … 1121 1257 ++i; 1122 1258 if (sym) 1123 gen_ send_intern(s);1259 gen_intern(s); 1124 1260 } 1125 1261 break; 1126 1262 } 1127 if(j >= 2) {1263 while (j >= 2) { 1128 1264 pop(); pop(); 1129 genop_ peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);1265 genop_1(s, OP_STRCAT, cursp()); 1130 1266 push(); 1131 j = 1;1267 j--; 1132 1268 } 1133 1269 tree = tree->cdr; … … 1136 1272 ++i; 1137 1273 if (sym) 1138 gen_ send_intern(s);1274 gen_intern(s); 1139 1275 } 1140 1276 pop_n(i); 1141 genop (s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), i));1277 genop_2(s, OP_ARRAY, cursp(), i); 1142 1278 push(); 1143 1279 } 1144 1280 else { 1145 1281 while (tree) { 1146 switch ( (intptr_t)tree->car->car) {1282 switch (nint(tree->car->car)) { 1147 1283 case NODE_BEGIN: case NODE_BLOCK: 1148 1284 codegen(s, tree->car, NOVAL); … … 1158 1294 int idx = new_lit(s, mrb_str_new_cstr(s->mrb, msg)); 1159 1295 1160 genop(s, MKOP_ABx(OP_ERR, 1, idx)); 1161 } 1162 1296 genop_1(s, OP_ERR, idx); 1297 } 1298 1299 #ifndef MRB_WITHOUT_FLOAT 1163 1300 static double 1164 1301 readint_float(codegen_scope *s, const char *p, int base) … … 1186 1323 return f; 1187 1324 } 1325 #endif 1188 1326 1189 1327 static mrb_int … … 1233 1371 gen_retval(codegen_scope *s, node *tree) 1234 1372 { 1235 if ((intptr_t)tree->car == NODE_SPLAT) { 1236 genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), 0)); 1237 push(); 1373 if (nint(tree->car) == NODE_SPLAT) { 1238 1374 codegen(s, tree, VAL); 1239 pop(); pop();1240 genop (s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));1375 pop(); 1376 genop_1(s, OP_ARYDUP, cursp()); 1241 1377 } 1242 1378 else { … … 1254 1390 if (!tree) { 1255 1391 if (val) { 1256 genop (s, MKOP_A(OP_LOADNIL, cursp()));1392 genop_1(s, OP_LOADNIL, cursp()); 1257 1393 push(); 1258 1394 } … … 1265 1401 } 1266 1402 if (s->irep && s->filename_index != tree->filename_index) { 1267 s->irep->filename = mrb_parser_get_filename(s->parser, s->filename_index); 1268 mrb_debug_info_append_file(s->mrb, s->irep, s->debug_start_pos, s->pc); 1403 mrb_sym fname = mrb_parser_get_filename(s->parser, s->filename_index); 1404 const char *filename = mrb_sym_name_len(s->mrb, fname, NULL); 1405 1406 mrb_debug_info_append_file(s->mrb, s->irep->debug_info, 1407 filename, s->lines, s->debug_start_pos, s->pc); 1269 1408 s->debug_start_pos = s->pc; 1270 1409 s->filename_index = tree->filename_index; 1271 s->filename = mrb_parser_get_filename(s->parser, tree->filename_index);1272 } 1273 1274 nt = (intptr_t)tree->car;1410 s->filename_sym = mrb_parser_get_filename(s->parser, tree->filename_index); 1411 } 1412 1413 nt = nint(tree->car); 1275 1414 s->lineno = tree->lineno; 1276 1415 tree = tree->cdr; … … 1278 1417 case NODE_BEGIN: 1279 1418 if (val && !tree) { 1280 genop (s, MKOP_A(OP_LOADNIL, cursp()));1419 genop_1(s, OP_LOADNIL, cursp()); 1281 1420 push(); 1282 1421 } … … 1289 1428 case NODE_RESCUE: 1290 1429 { 1291 int onerr,noexc, exend, pos1, pos2, tmp;1430 int noexc, exend, pos1, pos2, tmp; 1292 1431 struct loopinfo *lp; 1293 1432 1294 1433 if (tree->car == NULL) goto exit; 1295 onerr = genop(s, MKOP_Bx(OP_ONERR, 0));1296 1434 lp = loop_push(s, LOOP_BEGIN); 1297 lp->pc1 = onerr; 1435 lp->pc0 = new_label(s); 1436 lp->pc1 = genjmp(s, OP_ONERR, 0); 1298 1437 codegen(s, tree->car, VAL); 1299 1438 pop(); 1300 1439 lp->type = LOOP_RESCUE; 1301 noexc = gen op(s, MKOP_Bx(OP_JMP, 0));1302 dispatch(s, onerr);1440 noexc = genjmp(s, OP_JMP, 0); 1441 dispatch(s, lp->pc1); 1303 1442 tree = tree->cdr; 1304 1443 exend = 0; … … 1308 1447 int exc = cursp(); 1309 1448 1310 genop (s, MKOP_ABC(OP_RESCUE, exc, 0, 0));1449 genop_1(s, OP_EXCEPT, exc); 1311 1450 push(); 1312 1451 while (n2) { … … 1317 1456 pos2 = 0; 1318 1457 do { 1319 if (n4 && n4->car && (intptr_t)n4->car->car== NODE_SPLAT) {1458 if (n4 && n4->car && nint(n4->car->car) == NODE_SPLAT) { 1320 1459 codegen(s, n4->car, VAL); 1321 genop(s, MKOP_AB(OP_MOVE, cursp(), exc)); 1460 gen_move(s, cursp(), exc, 0); 1461 push_n(2); pop_n(2); /* space for one arg and a block */ 1322 1462 pop(); 1323 genop (s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1));1463 genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1); 1324 1464 } 1325 1465 else { … … 1328 1468 } 1329 1469 else { 1330 genop (s, MKOP_ABx(OP_GETCONST, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "StandardError"))));1470 genop_2(s, OP_GETCONST, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "StandardError"))); 1331 1471 push(); 1332 1472 } 1333 1473 pop(); 1334 genop (s, MKOP_ABC(OP_RESCUE, exc, cursp(), 1));1474 genop_2(s, OP_RESCUE, exc, cursp()); 1335 1475 } 1336 tmp = gen op(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));1476 tmp = genjmp2(s, OP_JMPIF, cursp(), pos2, val); 1337 1477 pos2 = tmp; 1338 1478 if (n4) { … … 1340 1480 } 1341 1481 } while (n4); 1342 pos1 = gen op(s, MKOP_sBx(OP_JMP, 0));1482 pos1 = genjmp(s, OP_JMP, 0); 1343 1483 dispatch_linked(s, pos2); 1344 1484 … … 1351 1491 if (val) pop(); 1352 1492 } 1353 tmp = gen op(s, MKOP_sBx(OP_JMP, exend));1493 tmp = genjmp(s, OP_JMP, exend); 1354 1494 exend = tmp; 1355 1495 n2 = n2->cdr; … … 1358 1498 if (pos1) { 1359 1499 dispatch(s, pos1); 1360 genop (s, MKOP_A(OP_RAISE, exc));1500 genop_1(s, OP_RAISE, exc); 1361 1501 } 1362 1502 } … … 1364 1504 tree = tree->cdr; 1365 1505 dispatch(s, noexc); 1366 genop (s, MKOP_A(OP_POPERR, 1));1506 genop_1(s, OP_POPERR, 1); 1367 1507 if (tree->car) { 1368 1508 codegen(s, tree->car, val); … … 1378 1518 case NODE_ENSURE: 1379 1519 if (!tree->cdr || !tree->cdr->cdr || 1380 ( (intptr_t)tree->cdr->cdr->car== NODE_BEGIN &&1520 (nint(tree->cdr->cdr->car) == NODE_BEGIN && 1381 1521 tree->cdr->cdr->cdr)) { 1382 1522 int idx; 1383 int epush = s->pc; 1384 1385 genop(s, MKOP_Bx(OP_EPUSH, 0)); 1523 1386 1524 s->ensure_level++; 1525 idx = scope_body(s, tree->cdr, NOVAL); 1526 genop_1(s, OP_EPUSH, idx); 1387 1527 codegen(s, tree->car, val); 1388 idx = scope_body(s, tree->cdr, NOVAL);1389 s->iseq[epush] = MKOP_Bx(OP_EPUSH, idx);1390 1528 s->ensure_level--; 1391 genop_ peep(s, MKOP_A(OP_EPOP, 1), NOVAL);1529 genop_1(s, OP_EPOP, 1); 1392 1530 } 1393 1531 else { /* empty ensure ignored */ … … 1400 1538 int idx = lambda_body(s, tree, 1); 1401 1539 1402 genop (s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_LAMBDA));1540 genop_2(s, OP_LAMBDA, cursp(), idx); 1403 1541 push(); 1404 1542 } … … 1409 1547 int idx = lambda_body(s, tree, 1); 1410 1548 1411 genop (s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_BLOCK));1549 genop_2(s, OP_BLOCK, cursp(), idx); 1412 1550 push(); 1413 1551 } … … 1416 1554 case NODE_IF: 1417 1555 { 1418 int pos1, pos2 ;1419 node *e = tree->cdr->cdr->car;1556 int pos1, pos2, nil_p = FALSE; 1557 node *elsepart = tree->cdr->cdr->car; 1420 1558 1421 1559 if (!tree->car) { 1422 codegen(s, e , val);1560 codegen(s, elsepart, val); 1423 1561 goto exit; 1424 1562 } 1425 switch ( (intptr_t)tree->car->car) {1563 switch (nint(tree->car->car)) { 1426 1564 case NODE_TRUE: 1427 1565 case NODE_INT: … … 1431 1569 case NODE_FALSE: 1432 1570 case NODE_NIL: 1433 codegen(s, e , val);1571 codegen(s, elsepart, val); 1434 1572 goto exit; 1435 } 1436 codegen(s, tree->car, VAL); 1573 case NODE_CALL: 1574 { 1575 node *n = tree->car->cdr; 1576 mrb_sym mid = nsym(n->cdr->car); 1577 mrb_sym mnil = mrb_intern_lit(s->mrb, "nil?"); 1578 if (mid == mnil && n->cdr->cdr->car == NULL) { 1579 nil_p = TRUE; 1580 codegen(s, n->car, VAL); 1581 } 1582 } 1583 break; 1584 } 1585 if (!nil_p) { 1586 codegen(s, tree->car, VAL); 1587 } 1437 1588 pop(); 1438 pos1 = genop_peep(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0), NOVAL); 1439 1440 codegen(s, tree->cdr->car, val); 1441 if (e) { 1589 if (val || tree->cdr->car) { 1590 if (nil_p) { 1591 pos2 = genjmp2(s, OP_JMPNIL, cursp(), 0, val); 1592 pos1 = genjmp(s, OP_JMP, 0); 1593 dispatch(s, pos2); 1594 } 1595 else { 1596 pos1 = genjmp2(s, OP_JMPNOT, cursp(), 0, val); 1597 } 1598 codegen(s, tree->cdr->car, val); 1442 1599 if (val) pop(); 1443 pos2 = genop(s, MKOP_sBx(OP_JMP, 0)); 1444 dispatch(s, pos1); 1445 codegen(s, e, val); 1446 dispatch(s, pos2); 1447 } 1448 else { 1449 if (val) { 1450 pop(); 1451 pos2 = genop(s, MKOP_sBx(OP_JMP, 0)); 1600 if (elsepart || val) { 1601 pos2 = genjmp(s, OP_JMP, 0); 1452 1602 dispatch(s, pos1); 1453 genop(s, MKOP_A(OP_LOADNIL, cursp()));1603 codegen(s, elsepart, val); 1454 1604 dispatch(s, pos2); 1455 push();1456 1605 } 1457 1606 else { 1458 1607 dispatch(s, pos1); 1608 } 1609 } 1610 else { /* empty then-part */ 1611 if (elsepart) { 1612 if (nil_p) { 1613 pos1 = genjmp2(s, OP_JMPNIL, cursp(), 0, val); 1614 } 1615 else { 1616 pos1 = genjmp2(s, OP_JMPIF, cursp(), 0, val); 1617 } 1618 codegen(s, elsepart, val); 1619 dispatch(s, pos1); 1620 } 1621 else if (val && !nil_p) { 1622 genop_1(s, OP_LOADNIL, cursp()); 1623 push(); 1459 1624 } 1460 1625 } … … 1468 1633 codegen(s, tree->car, VAL); 1469 1634 pop(); 1470 pos = gen op(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0));1635 pos = genjmp2(s, OP_JMPNOT, cursp(), 0, val); 1471 1636 codegen(s, tree->cdr, val); 1472 1637 dispatch(s, pos); … … 1480 1645 codegen(s, tree->car, VAL); 1481 1646 pop(); 1482 pos = gen op(s, MKOP_AsBx(OP_JMPIF, cursp(), 0));1647 pos = genjmp2(s, OP_JMPIF, cursp(), 0, val); 1483 1648 codegen(s, tree->cdr, val); 1484 1649 dispatch(s, pos); … … 1490 1655 struct loopinfo *lp = loop_push(s, LOOP_NORMAL); 1491 1656 1492 lp->pc1 = genop(s, MKOP_sBx(OP_JMP, 0)); 1657 lp->pc0 = new_label(s); 1658 lp->pc1 = genjmp(s, OP_JMP, 0); 1493 1659 lp->pc2 = new_label(s); 1494 1660 codegen(s, tree->cdr, NOVAL); … … 1496 1662 codegen(s, tree->car, VAL); 1497 1663 pop(); 1498 gen op(s, MKOP_AsBx(OP_JMPIF, cursp(), lp->pc2 - s->pc));1664 genjmp2(s, OP_JMPIF, cursp(), lp->pc2, NOVAL); 1499 1665 1500 1666 loop_pop(s, val); … … 1506 1672 struct loopinfo *lp = loop_push(s, LOOP_NORMAL); 1507 1673 1508 lp->pc1 = genop(s, MKOP_sBx(OP_JMP, 0)); 1674 lp->pc0 = new_label(s); 1675 lp->pc1 = genjmp(s, OP_JMP, 0); 1509 1676 lp->pc2 = new_label(s); 1510 1677 codegen(s, tree->cdr, NOVAL); … … 1512 1679 codegen(s, tree->car, VAL); 1513 1680 pop(); 1514 gen op(s, MKOP_AsBx(OP_JMPNOT, cursp(), lp->pc2 - s->pc));1681 genjmp2(s, OP_JMPNOT, cursp(), lp->pc2, NOVAL); 1515 1682 1516 1683 loop_pop(s, val); … … 1541 1708 codegen(s, n->car, VAL); 1542 1709 if (head) { 1543 gen op(s, MKOP_AB(OP_MOVE, cursp(), head));1544 p op();1545 if ( (intptr_t)n->car->car== NODE_SPLAT) {1546 genop (s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1));1710 gen_move(s, cursp(), head, 0); 1711 push(); push(); pop(); pop(); pop(); 1712 if (nint(n->car->car) == NODE_SPLAT) { 1713 genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1); 1547 1714 } 1548 1715 else { 1549 genop (s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "===")), 1));1716 genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "===")), 1); 1550 1717 } 1551 1718 } … … 1553 1720 pop(); 1554 1721 } 1555 tmp = gen op(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));1722 tmp = genjmp2(s, OP_JMPIF, cursp(), pos2, NOVAL); 1556 1723 pos2 = tmp; 1557 1724 n = n->cdr; 1558 1725 } 1559 1726 if (tree->car->car) { 1560 pos1 = gen op(s, MKOP_sBx(OP_JMP, 0));1727 pos1 = genjmp(s, OP_JMP, 0); 1561 1728 dispatch_linked(s, pos2); 1562 1729 } 1563 1730 codegen(s, tree->car->cdr, val); 1564 1731 if (val) pop(); 1565 tmp = gen op(s, MKOP_sBx(OP_JMP, pos3));1732 tmp = genjmp(s, OP_JMP, pos3); 1566 1733 pos3 = tmp; 1567 1734 if (pos1) dispatch(s, pos1); … … 1570 1737 if (val) { 1571 1738 int pos = cursp(); 1572 genop (s, MKOP_A(OP_LOADNIL, cursp()));1739 genop_1(s, OP_LOADNIL, cursp()); 1573 1740 if (pos3) dispatch_linked(s, pos3); 1574 1741 if (head) pop(); 1575 1742 if (cursp() != pos) { 1576 gen op(s, MKOP_AB(OP_MOVE, cursp(), pos));1743 gen_move(s, cursp(), pos, 0); 1577 1744 } 1578 1745 push(); … … 1606 1773 if (val) { 1607 1774 pop(); pop(); 1608 genop (s, MKOP_ABC(OP_RANGE, cursp(), cursp(), FALSE));1775 genop_1(s, OP_RANGE_INC, cursp()); 1609 1776 push(); 1610 1777 } … … 1616 1783 if (val) { 1617 1784 pop(); pop(); 1618 genop (s, MKOP_ABC(OP_RANGE, cursp(), cursp(), TRUE));1785 genop_1(s, OP_RANGE_EXC, cursp()); 1619 1786 push(); 1620 1787 } … … 1623 1790 case NODE_COLON2: 1624 1791 { 1625 int sym = new_sym(s, sym(tree->cdr));1792 int sym = new_sym(s, nsym(tree->cdr)); 1626 1793 1627 1794 codegen(s, tree->car, VAL); 1628 1795 pop(); 1629 genop (s, MKOP_ABx(OP_GETMCNST, cursp(), sym));1796 genop_2(s, OP_GETMCNST, cursp(), sym); 1630 1797 if (val) push(); 1631 1798 } … … 1634 1801 case NODE_COLON3: 1635 1802 { 1636 int sym = new_sym(s, sym(tree));1637 1638 genop (s, MKOP_A(OP_OCLASS, cursp()));1639 genop (s, MKOP_ABx(OP_GETMCNST, cursp(), sym));1803 int sym = new_sym(s, nsym(tree)); 1804 1805 genop_1(s, OP_OCLASS, cursp()); 1806 genop_2(s, OP_GETMCNST, cursp(), sym); 1640 1807 if (val) push(); 1641 1808 } … … 1650 1817 if (val) { 1651 1818 pop_n(n); 1652 genop (s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n));1819 genop_2(s, OP_ARRAY, cursp(), n); 1653 1820 push(); 1654 1821 } … … 1661 1828 1662 1829 case NODE_HASH: 1830 case NODE_KW_HASH: 1663 1831 { 1664 1832 int len = 0; … … 1666 1834 1667 1835 while (tree) { 1668 codegen(s, tree->car->car, val); 1669 codegen(s, tree->car->cdr, val); 1670 len++; 1836 if (nint(tree->car->car->car) == NODE_KW_REST_ARGS) { 1837 if (len > 0) { 1838 pop_n(len*2); 1839 if (!update) { 1840 genop_2(s, OP_HASH, cursp(), len); 1841 } 1842 else { 1843 pop(); 1844 genop_2(s, OP_HASHADD, cursp(), len); 1845 } 1846 push(); 1847 } 1848 codegen(s, tree->car->cdr, VAL); 1849 if (len > 0 || update) { 1850 pop(); pop(); 1851 genop_1(s, OP_HASHCAT, cursp()); 1852 push(); 1853 } 1854 update = TRUE; 1855 len = 0; 1856 } 1857 else { 1858 codegen(s, tree->car->car, val); 1859 codegen(s, tree->car->cdr, val); 1860 len++; 1861 } 1671 1862 tree = tree->cdr; 1672 if (val && len == 126) {1863 if (val && len == 255) { 1673 1864 pop_n(len*2); 1674 genop(s, MKOP_ABC(OP_HASH, cursp(), cursp(), len)); 1675 if (update) { 1865 if (!update) { 1866 genop_2(s, OP_HASH, cursp(), len); 1867 } 1868 else { 1676 1869 pop(); 1677 genop (s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__update")), 1));1870 genop_2(s, OP_HASHADD, cursp(), len); 1678 1871 } 1679 1872 push(); … … 1684 1877 if (val) { 1685 1878 pop_n(len*2); 1686 genop(s, MKOP_ABC(OP_HASH, cursp(), cursp(), len)); 1687 if (update) { 1879 if (!update) { 1880 genop_2(s, OP_HASH, cursp(), len); 1881 } 1882 else { 1688 1883 pop(); 1689 genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__update")), 1)); 1884 if (len > 0) { 1885 genop_2(s, OP_HASHADD, cursp(), len); 1886 } 1690 1887 } 1691 1888 push(); … … 1710 1907 int rhs = cursp(); 1711 1908 1712 if ( (intptr_t)t->car== NODE_ARRAY && t->cdr && nosplat(t->cdr)) {1909 if (nint(t->car) == NODE_ARRAY && t->cdr && nosplat(t->cdr)) { 1713 1910 /* fixed rhs */ 1714 1911 t = t->cdr; … … 1728 1925 } 1729 1926 else { 1730 genop (s, MKOP_A(OP_LOADNIL, rhs+n));1927 genop_1(s, OP_LOADNIL, rhs+n); 1731 1928 gen_assignment(s, t->car, rhs+n, NOVAL); 1732 1929 } … … 1752 1949 rn = len - post - n; 1753 1950 } 1754 genop (s, MKOP_ABC(OP_ARRAY, cursp(), rhs+n, rn));1951 genop_3(s, OP_ARRAY2, cursp(), rhs+n, rn); 1755 1952 gen_assignment(s, t->car, cursp(), NOVAL); 1756 1953 n += rn; … … 1767 1964 pop_n(len); 1768 1965 if (val) { 1769 genop (s, MKOP_ABC(OP_ARRAY, rhs, rhs, len));1966 genop_2(s, OP_ARRAY, rhs, len); 1770 1967 push(); 1771 1968 } … … 1784 1981 case NODE_OP_ASGN: 1785 1982 { 1786 mrb_sym sym = sym(tree->cdr->car);1983 mrb_sym sym = nsym(tree->cdr->car); 1787 1984 mrb_int len; 1788 const char *name = mrb_sym 2name_len(s->mrb, sym, &len);1985 const char *name = mrb_sym_name_len(s->mrb, sym, &len); 1789 1986 int idx, callargs = -1, vsp = -1; 1790 1987 1791 1988 if ((len == 2 && name[0] == '|' && name[1] == '|') && 1792 ( (intptr_t)tree->car->car== NODE_CONST ||1793 (intptr_t)tree->car->car== NODE_CVAR)) {1989 (nint(tree->car->car) == NODE_CONST || 1990 nint(tree->car->car) == NODE_CVAR)) { 1794 1991 int onerr, noexc, exc; 1795 1992 struct loopinfo *lp; 1796 1993 1797 onerr = gen op(s, MKOP_Bx(OP_ONERR, 0));1994 onerr = genjmp(s, OP_ONERR, 0); 1798 1995 lp = loop_push(s, LOOP_BEGIN); 1799 1996 lp->pc1 = onerr; … … 1801 1998 codegen(s, tree->car, VAL); 1802 1999 lp->type = LOOP_RESCUE; 1803 genop (s, MKOP_A(OP_POPERR, 1));1804 noexc = gen op(s, MKOP_Bx(OP_JMP, 0));2000 genop_1(s, OP_POPERR, 1); 2001 noexc = genjmp(s, OP_JMP, 0); 1805 2002 dispatch(s, onerr); 1806 genop (s, MKOP_ABC(OP_RESCUE, exc, 0, 0));1807 genop (s, MKOP_A(OP_LOADF, exc));2003 genop_1(s, OP_EXCEPT, exc); 2004 genop_1(s, OP_LOADF, exc); 1808 2005 dispatch(s, noexc); 1809 2006 loop_pop(s, NOVAL); 1810 2007 } 1811 else if ( (intptr_t)tree->car->car== NODE_CALL) {2008 else if (nint(tree->car->car) == NODE_CALL) { 1812 2009 node *n = tree->car->cdr; 2010 int base, i, nargs = 0; 2011 callargs = 0; 1813 2012 1814 2013 if (val) { … … 1817 2016 } 1818 2017 codegen(s, n->car, VAL); /* receiver */ 1819 idx = new_msym(s, sym(n->cdr->car)); 2018 idx = new_sym(s, nsym(n->cdr->car)); 2019 base = cursp()-1; 1820 2020 if (n->cdr->cdr->car) { 1821 int base = cursp()-1; 1822 int nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 1); 1823 1824 /* copy receiver and arguments */ 2021 nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 1); 1825 2022 if (nargs >= 0) { 1826 int i;1827 1828 genop(s, MKOP_AB(OP_MOVE, cursp(), base));1829 for (i=0; i<nargs; i++) {1830 genop(s, MKOP_AB(OP_MOVE, cursp()+i+1, base+i+1));1831 }1832 push_n(nargs+1);1833 pop_n(nargs+1);1834 2023 callargs = nargs; 1835 2024 } 1836 else { 1837 /* varargs */ 2025 else { /* varargs */ 1838 2026 push(); 1839 genop(s, MKOP_AB(OP_MOVE, cursp(), base)); 1840 genop(s, MKOP_AB(OP_MOVE, cursp()+1, base+1)); 2027 nargs = 1; 1841 2028 callargs = CALL_MAXARGS; 1842 2029 } 1843 genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs)); 1844 } 1845 else { 1846 genop(s, MKOP_AB(OP_MOVE, cursp(), cursp()-1)); 1847 genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 0)); 1848 callargs = 0; 1849 } 2030 } 2031 /* copy receiver and arguments */ 2032 gen_move(s, cursp(), base, 1); 2033 for (i=0; i<nargs; i++) { 2034 gen_move(s, cursp()+i+1, base+i+1, 1); 2035 } 2036 push_n(nargs+2);pop_n(nargs+2); /* space for receiver, arguments and a block */ 2037 genop_3(s, OP_SEND, cursp(), idx, callargs); 1850 2038 push(); 1851 2039 } … … 1861 2049 if (val) { 1862 2050 if (vsp >= 0) { 1863 gen op(s, MKOP_AB(OP_MOVE, vsp, cursp()));1864 } 1865 pos = gen op(s, MKOP_AsBx(name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0));2051 gen_move(s, vsp, cursp(), 1); 2052 } 2053 pos = genjmp2(s, name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0, val); 1866 2054 } 1867 2055 else { 1868 pos = gen op_peep(s, MKOP_AsBx(name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0), NOVAL);2056 pos = genjmp2(s, name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0, val); 1869 2057 } 1870 2058 codegen(s, tree->cdr->cdr->car, VAL); 1871 2059 pop(); 1872 2060 if (val && vsp >= 0) { 1873 genop(s, MKOP_AB(OP_MOVE, vsp, cursp())); 1874 } 1875 if ((intptr_t)tree->car->car == NODE_CALL) { 1876 mrb_sym m = sym(tree->car->cdr->cdr->car); 1877 mrb_sym m2 = attrsym(s, m); 1878 1879 idx = new_msym(s, m2); 1880 pop(); 2061 gen_move(s, vsp, cursp(), 1); 2062 } 2063 if (nint(tree->car->car) == NODE_CALL) { 1881 2064 if (callargs == CALL_MAXARGS) { 1882 genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));1883 2065 pop(); 1884 genop (s, MKOP_ABC(OP_SEND, cursp(), idx, callargs));2066 genop_1(s, OP_ARYPUSH, cursp()); 1885 2067 } 1886 2068 else { 1887 2069 pop_n(callargs); 1888 genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs+1)); 1889 } 2070 callargs++; 2071 } 2072 pop(); 2073 idx = new_sym(s, attrsym(s, nsym(tree->car->cdr->cdr->car))); 2074 genop_3(s, OP_SEND, cursp(), idx, callargs); 1890 2075 } 1891 2076 else { … … 1899 2084 pop(); pop(); 1900 2085 1901 idx = new_msym(s, sym);1902 2086 if (len == 1 && name[0] == '+') { 1903 gen op_peep(s, MKOP_ABC(OP_ADD, cursp(), idx, 1), val);2087 gen_addsub(s, OP_ADD, cursp()); 1904 2088 } 1905 2089 else if (len == 1 && name[0] == '-') { 1906 gen op_peep(s, MKOP_ABC(OP_SUB, cursp(), idx, 1), val);2090 gen_addsub(s, OP_SUB, cursp()); 1907 2091 } 1908 2092 else if (len == 1 && name[0] == '*') { 1909 genop (s, MKOP_ABC(OP_MUL, cursp(), idx, 1));2093 genop_1(s, OP_MUL, cursp()); 1910 2094 } 1911 2095 else if (len == 1 && name[0] == '/') { 1912 genop (s, MKOP_ABC(OP_DIV, cursp(), idx, 1));2096 genop_1(s, OP_DIV, cursp()); 1913 2097 } 1914 2098 else if (len == 1 && name[0] == '<') { 1915 genop (s, MKOP_ABC(OP_LT, cursp(), idx, 1));2099 genop_1(s, OP_LT, cursp()); 1916 2100 } 1917 2101 else if (len == 2 && name[0] == '<' && name[1] == '=') { 1918 genop (s, MKOP_ABC(OP_LE, cursp(), idx, 1));2102 genop_1(s, OP_LE, cursp()); 1919 2103 } 1920 2104 else if (len == 1 && name[0] == '>') { 1921 genop (s, MKOP_ABC(OP_GT, cursp(), idx, 1));2105 genop_1(s, OP_GT, cursp()); 1922 2106 } 1923 2107 else if (len == 2 && name[0] == '>' && name[1] == '=') { 1924 genop (s, MKOP_ABC(OP_GE, cursp(), idx, 1));2108 genop_1(s, OP_GE, cursp()); 1925 2109 } 1926 2110 else { 1927 genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 1)); 2111 idx = new_sym(s, sym); 2112 genop_3(s, OP_SEND, cursp(), idx, 1); 1928 2113 } 1929 2114 if (callargs < 0) { … … 1932 2117 else { 1933 2118 if (val && vsp >= 0) { 1934 gen op(s, MKOP_AB(OP_MOVE, vsp, cursp()));2119 gen_move(s, vsp, cursp(), 0); 1935 2120 } 1936 2121 if (callargs == CALL_MAXARGS) { 1937 2122 pop(); 1938 genop (s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));2123 genop_1(s, OP_ARYPUSH, cursp()); 1939 2124 } 1940 2125 else { … … 1943 2128 } 1944 2129 pop(); 1945 idx = new_ msym(s, attrsym(s,sym(tree->car->cdr->cdr->car)));1946 genop (s, MKOP_ABC(OP_SEND, cursp(), idx, callargs));2130 idx = new_sym(s, attrsym(s,nsym(tree->car->cdr->cdr->car))); 2131 genop_3(s, OP_SEND, cursp(), idx, callargs); 1947 2132 } 1948 2133 } … … 1961 2146 if (!s2) break; 1962 2147 } 1963 genop (s, MKOP_ABx(OP_ARGARY, cursp(), (lv & 0xf)));2148 genop_2S(s, OP_ARGARY, cursp(), (lv & 0xf)); 1964 2149 push(); push(); /* ARGARY pushes two values */ 1965 2150 pop(); pop(); … … 1979 2164 } 1980 2165 else { 1981 genop (s, MKOP_A(OP_LOADNIL, cursp()));2166 genop_1(s, OP_LOADNIL, cursp()); 1982 2167 push(); pop(); 1983 2168 } 1984 2169 pop_n(n+1); 1985 2170 if (sendv) n = CALL_MAXARGS; 1986 genop (s, MKOP_ABC(OP_SUPER, cursp(), 0, n));2171 genop_2(s, OP_SUPER, cursp(), n); 1987 2172 if (val) push(); 1988 2173 } … … 2001 2186 } 2002 2187 if (s2) ainfo = s2->ainfo; 2003 genop (s, MKOP_ABx(OP_ARGARY, cursp(), (ainfo<<4)|(lv & 0xf)));2188 genop_2S(s, OP_ARGARY, cursp(), (ainfo<<4)|(lv & 0xf)); 2004 2189 push(); push(); pop(); /* ARGARY pushes two values */ 2005 2190 if (tree && tree->cdr) { … … 2008 2193 } 2009 2194 pop(); pop(); 2010 genop (s, MKOP_ABC(OP_SUPER, cursp(), 0, CALL_MAXARGS));2195 genop_2(s, OP_SUPER, cursp(), CALL_MAXARGS); 2011 2196 if (val) push(); 2012 2197 } … … 2018 2203 } 2019 2204 else { 2020 genop (s, MKOP_A(OP_LOADNIL, cursp()));2205 genop_1(s, OP_LOADNIL, cursp()); 2021 2206 } 2022 2207 if (s->loop) { 2023 gen op(s, MKOP_AB(OP_RETURN, cursp(), OP_R_RETURN));2208 gen_return(s, OP_RETURN_BLK, cursp()); 2024 2209 } 2025 2210 else { 2026 gen op_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);2211 gen_return(s, OP_RETURN, cursp()); 2027 2212 } 2028 2213 if (val) push(); … … 2049 2234 } 2050 2235 } 2236 push();pop(); /* space for a block */ 2051 2237 pop_n(n+1); 2052 genop (s, MKOP_ABx(OP_BLKPUSH, cursp(), (ainfo<<4)|(lv & 0xf)));2238 genop_2S(s, OP_BLKPUSH, cursp(), (ainfo<<4)|(lv & 0xf)); 2053 2239 if (sendv) n = CALL_MAXARGS; 2054 genop (s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "call")), n));2240 genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "call")), n); 2055 2241 if (val) push(); 2056 2242 } … … 2068 2254 else if (s->loop->type == LOOP_NORMAL) { 2069 2255 if (s->ensure_level > s->loop->ensure_level) { 2070 genop_ peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);2256 genop_1(s, OP_EPOP, s->ensure_level - s->loop->ensure_level); 2071 2257 } 2072 2258 codegen(s, tree, NOVAL); 2073 gen op(s, MKOP_sBx(OP_JMP, s->loop->pc1 - s->pc));2259 genjmp(s, OP_JMP, s->loop->pc0); 2074 2260 } 2075 2261 else { … … 2079 2265 } 2080 2266 else { 2081 genop (s, MKOP_A(OP_LOADNIL, cursp()));2082 } 2083 gen op_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);2267 genop_1(s, OP_LOADNIL, cursp()); 2268 } 2269 gen_return(s, OP_RETURN, cursp()); 2084 2270 } 2085 2271 if (val) push(); … … 2092 2278 else { 2093 2279 if (s->ensure_level > s->loop->ensure_level) { 2094 genop_ peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);2095 } 2096 gen op(s, MKOP_sBx(OP_JMP, s->loop->pc2 - s->pc));2280 genop_1(s, OP_EPOP, s->ensure_level - s->loop->ensure_level); 2281 } 2282 genjmp(s, OP_JMP, s->loop->pc2); 2097 2283 } 2098 2284 if (val) push(); … … 2121 2307 else { 2122 2308 if (n > 0) { 2123 while (n--) { 2124 genop_peep(s, MKOP_A(OP_POPERR, 1), NOVAL); 2125 } 2309 genop_1(s, OP_POPERR, n); 2126 2310 } 2127 2311 if (s->ensure_level > lp->ensure_level) { 2128 genop_ peep(s, MKOP_A(OP_EPOP, s->ensure_level - lp->ensure_level), NOVAL);2129 } 2130 gen op(s, MKOP_sBx(OP_JMP, lp->pc1 - s->pc));2312 genop_1(s, OP_EPOP, s->ensure_level - lp->ensure_level); 2313 } 2314 genjmp(s, OP_JMP, lp->pc0); 2131 2315 } 2132 2316 } … … 2137 2321 case NODE_LVAR: 2138 2322 if (val) { 2139 int idx = lv_idx(s, sym(tree));2323 int idx = lv_idx(s, nsym(tree)); 2140 2324 2141 2325 if (idx > 0) { 2142 genop_peep(s, MKOP_AB(OP_MOVE, cursp(), idx), NOVAL); 2326 gen_move(s, cursp(), idx, val); 2327 if (val && on_eval(s)) genop_0(s, OP_NOP); 2143 2328 } 2144 2329 else { … … 2147 2332 2148 2333 while (up) { 2149 idx = lv_idx(up, sym(tree));2334 idx = lv_idx(up, nsym(tree)); 2150 2335 if (idx > 0) { 2151 genop (s, MKOP_ABC(OP_GETUPVAR, cursp(), idx, lv));2336 genop_3(s, OP_GETUPVAR, cursp(), idx, lv); 2152 2337 break; 2153 2338 } … … 2160 2345 break; 2161 2346 2347 case NODE_NVAR: 2348 if (val) { 2349 int idx = nint(tree); 2350 2351 gen_move(s, cursp(), idx, val); 2352 if (val && on_eval(s)) genop_0(s, OP_NOP); 2353 2354 push(); 2355 } 2356 break; 2357 2162 2358 case NODE_GVAR: 2163 if (val){2164 int sym = new_sym(s, sym(tree));2165 2166 genop (s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));2167 push();2359 { 2360 int sym = new_sym(s, nsym(tree)); 2361 2362 genop_2(s, OP_GETGV, cursp(), sym); 2363 if (val) push(); 2168 2364 } 2169 2365 break; 2170 2366 2171 2367 case NODE_IVAR: 2172 if (val){2173 int sym = new_sym(s, sym(tree));2174 2175 genop (s, MKOP_ABx(OP_GETIV, cursp(), sym));2176 push();2368 { 2369 int sym = new_sym(s, nsym(tree)); 2370 2371 genop_2(s, OP_GETIV, cursp(), sym); 2372 if (val) push(); 2177 2373 } 2178 2374 break; 2179 2375 2180 2376 case NODE_CVAR: 2181 if (val){2182 int sym = new_sym(s, sym(tree));2183 2184 genop (s, MKOP_ABx(OP_GETCV, cursp(), sym));2185 push();2377 { 2378 int sym = new_sym(s, nsym(tree)); 2379 2380 genop_2(s, OP_GETCV, cursp(), sym); 2381 if (val) push(); 2186 2382 } 2187 2383 break; … … 2189 2385 case NODE_CONST: 2190 2386 { 2191 int sym = new_sym(s, sym(tree)); 2192 2193 genop(s, MKOP_ABx(OP_GETCONST, cursp(), sym)); 2194 if (val) { 2195 push(); 2196 } 2197 } 2198 break; 2199 2200 case NODE_DEFINED: 2201 codegen(s, tree, VAL); 2387 int sym = new_sym(s, nsym(tree)); 2388 2389 genop_2(s, OP_GETCONST, cursp(), sym); 2390 if (val) push(); 2391 } 2202 2392 break; 2203 2393 2204 2394 case NODE_BACK_REF: 2205 2395 if (val) { 2206 char buf[3]; 2207 int sym; 2208 2209 buf[0] = '$'; 2210 buf[1] = (char)(intptr_t)tree; 2211 buf[2] = 0; 2212 sym = new_sym(s, mrb_intern_cstr(s->mrb, buf)); 2213 genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym)); 2396 char buf[] = {'$', nchar(tree)}; 2397 int sym = new_sym(s, mrb_intern(s->mrb, buf, sizeof(buf))); 2398 2399 genop_2(s, OP_GETGV, cursp(), sym); 2214 2400 push(); 2215 2401 } … … 2222 2408 int sym; 2223 2409 2224 str = mrb_format(mrb, "$% S", mrb_fixnum_value((mrb_int)(intptr_t)tree));2410 str = mrb_format(mrb, "$%d", nint(tree)); 2225 2411 sym = new_sym(s, mrb_intern_str(mrb, str)); 2226 genop (s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));2412 genop_2(s, OP_GETGV, cursp(), sym); 2227 2413 push(); 2228 2414 } … … 2234 2420 2235 2421 case NODE_BLOCK_ARG: 2236 codegen(s, tree, VAL);2422 codegen(s, tree, val); 2237 2423 break; 2238 2424 … … 2240 2426 if (val) { 2241 2427 char *p = (char*)tree->car; 2242 int base = (intptr_t)tree->cdr->car;2428 int base = nint(tree->cdr->car); 2243 2429 mrb_int i; 2244 mrb_code co;2245 2430 mrb_bool overflow; 2246 2431 2247 2432 i = readint_mrb_int(s, p, base, FALSE, &overflow); 2433 #ifndef MRB_WITHOUT_FLOAT 2248 2434 if (overflow) { 2249 2435 double f = readint_float(s, p, base); 2250 2436 int off = new_lit(s, mrb_float_value(s->mrb, f)); 2251 2437 2252 genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); 2253 } 2254 else { 2255 if (i < MAXARG_sBx && i > -MAXARG_sBx) { 2256 co = MKOP_AsBx(OP_LOADI, cursp(), i); 2257 } 2438 genop_2(s, OP_LOADL, cursp(), off); 2439 } 2440 else 2441 #endif 2442 { 2443 if (i == -1) genop_1(s, OP_LOADI__1, cursp()); 2444 else if (i < 0) genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i); 2445 else if (i < 8) genop_1(s, OP_LOADI_0 + (uint8_t)i, cursp()); 2446 else if (i <= 0xffff) genop_2(s, OP_LOADI, cursp(), (uint16_t)i); 2258 2447 else { 2259 2448 int off = new_lit(s, mrb_fixnum_value(i)); 2260 co = MKOP_ABx(OP_LOADL, cursp(), off); 2261 } 2262 genop(s, co); 2449 genop_2(s, OP_LOADL, cursp(), off); 2450 } 2263 2451 } 2264 2452 push(); … … 2266 2454 break; 2267 2455 2456 #ifndef MRB_WITHOUT_FLOAT 2268 2457 case NODE_FLOAT: 2269 2458 if (val) { … … 2272 2461 int off = new_lit(s, mrb_float_value(s->mrb, f)); 2273 2462 2274 genop (s, MKOP_ABx(OP_LOADL, cursp(), off));2463 genop_2(s, OP_LOADL, cursp(), off); 2275 2464 push(); 2276 2465 } 2277 2466 break; 2467 #endif 2278 2468 2279 2469 case NODE_NEGATE: 2280 2470 { 2281 nt = (intptr_t)tree->car; 2282 tree = tree->cdr; 2471 nt = nint(tree->car); 2283 2472 switch (nt) { 2473 #ifndef MRB_WITHOUT_FLOAT 2284 2474 case NODE_FLOAT: 2285 2475 if (val) { 2286 char *p = (char*)tree ;2476 char *p = (char*)tree->cdr; 2287 2477 mrb_float f = mrb_float_read(p, NULL); 2288 2478 int off = new_lit(s, mrb_float_value(s->mrb, -f)); 2289 2479 2290 genop (s, MKOP_ABx(OP_LOADL, cursp(), off));2480 genop_2(s, OP_LOADL, cursp(), off); 2291 2481 push(); 2292 2482 } 2293 2483 break; 2484 #endif 2294 2485 2295 2486 case NODE_INT: 2296 2487 if (val) { 2297 char *p = (char*)tree->c ar;2298 int base = (intptr_t)tree->cdr->car;2488 char *p = (char*)tree->cdr->car; 2489 int base = nint(tree->cdr->cdr->car); 2299 2490 mrb_int i; 2300 mrb_code co;2301 2491 mrb_bool overflow; 2302 2492 2303 2493 i = readint_mrb_int(s, p, base, TRUE, &overflow); 2494 #ifndef MRB_WITHOUT_FLOAT 2304 2495 if (overflow) { 2305 2496 double f = readint_float(s, p, base); 2306 2497 int off = new_lit(s, mrb_float_value(s->mrb, -f)); 2307 2498 2308 genop (s, MKOP_ABx(OP_LOADL, cursp(), off));2499 genop_2(s, OP_LOADL, cursp(), off); 2309 2500 } 2310 2501 else { 2311 if (i < MAXARG_sBx && i > -MAXARG_sBx) { 2312 co = MKOP_AsBx(OP_LOADI, cursp(), i); 2502 #endif 2503 if (i == -1) genop_1(s, OP_LOADI__1, cursp()); 2504 else if (i >= -0xffff) { 2505 genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i); 2313 2506 } 2314 2507 else { 2315 2508 int off = new_lit(s, mrb_fixnum_value(i)); 2316 co = MKOP_ABx(OP_LOADL, cursp(), off);2509 genop_2(s, OP_LOADL, cursp(), off); 2317 2510 } 2318 genop(s, co); 2319 } 2511 #ifndef MRB_WITHOUT_FLOAT 2512 } 2513 #endif 2320 2514 push(); 2321 2515 } … … 2324 2518 default: 2325 2519 if (val) { 2326 int sym = new_msym(s, mrb_intern_lit(s->mrb, "-")); 2327 2328 genop(s, MKOP_ABx(OP_LOADI, cursp(), 0)); 2520 int sym = new_sym(s, mrb_intern_lit(s->mrb, "-@")); 2521 codegen(s, tree, VAL); 2522 pop(); 2523 genop_3(s, OP_SEND, cursp(), sym, 0); 2329 2524 push(); 2330 codegen(s, tree, VAL);2331 pop(); pop();2332 genop(s, MKOP_ABC(OP_SUB, cursp(), sym, 2));2333 2525 } 2334 2526 else { … … 2348 2540 2349 2541 mrb_gc_arena_restore(s->mrb, ai); 2350 genop (s, MKOP_ABx(OP_STRING, cursp(), off));2542 genop_2(s, OP_STRING, cursp(), off); 2351 2543 push(); 2352 2544 } … … 2361 2553 2362 2554 if (!n) { 2363 genop (s, MKOP_A(OP_LOADNIL, cursp()));2555 genop_1(s, OP_LOADNIL, cursp()); 2364 2556 push(); 2365 2557 break; … … 2370 2562 codegen(s, n->car, VAL); 2371 2563 pop(); pop(); 2372 genop_ peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);2564 genop_1(s, OP_STRCAT, cursp()); 2373 2565 push(); 2374 2566 n = n->cdr; … … 2379 2571 2380 2572 while (n) { 2381 if ( (intptr_t)n->car->car!= NODE_STR) {2573 if (nint(n->car->car) != NODE_STR) { 2382 2574 codegen(s, n->car, NOVAL); 2383 2575 } … … 2401 2593 int sym = new_sym(s, mrb_intern_lit(s->mrb, "Kernel")); 2402 2594 2403 genop (s, MKOP_A(OP_LOADSELF, cursp()));2595 genop_1(s, OP_LOADSELF, cursp()); 2404 2596 push(); 2405 2597 codegen(s, tree->car, VAL); 2406 2598 n = tree->cdr; 2407 2599 while (n) { 2408 if ( (intptr_t)n->car->car== NODE_XSTR) {2600 if (nint(n->car->car) == NODE_XSTR) { 2409 2601 n->car->car = (struct mrb_ast_node*)(intptr_t)NODE_STR; 2410 2602 mrb_assert(!n->cdr); /* must be the end */ … … 2412 2604 codegen(s, n->car, VAL); 2413 2605 pop(); pop(); 2414 genop_ peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);2606 genop_1(s, OP_STRCAT, cursp()); 2415 2607 push(); 2416 2608 n = n->cdr; … … 2419 2611 pop_n(3); 2420 2612 sym = new_sym(s, mrb_intern_lit(s->mrb, "`")); 2421 genop (s, MKOP_ABC(OP_SEND, cursp(), sym, 1));2613 genop_3(s, OP_SEND, cursp(), sym, 1); 2422 2614 if (val) push(); 2423 2615 mrb_gc_arena_restore(s->mrb, ai); … … 2433 2625 int sym; 2434 2626 2435 genop (s, MKOP_A(OP_LOADSELF, cursp()));2627 genop_1(s, OP_LOADSELF, cursp()); 2436 2628 push(); 2437 genop (s, MKOP_ABx(OP_STRING, cursp(), off));2629 genop_2(s, OP_STRING, cursp(), off); 2438 2630 push(); push(); 2439 2631 pop_n(3); 2440 2632 sym = new_sym(s, mrb_intern_lit(s->mrb, "`")); 2441 genop (s, MKOP_ABC(OP_SEND, cursp(), sym, 1));2633 genop_3(s, OP_SEND, cursp(), sym, 1); 2442 2634 if (val) push(); 2443 2635 mrb_gc_arena_restore(s->mrb, ai); … … 2455 2647 int argc = 1; 2456 2648 2457 genop (s, MKOP_A(OP_OCLASS, cursp()));2458 genop (s, MKOP_ABx(OP_GETMCNST, cursp(), sym));2649 genop_1(s, OP_OCLASS, cursp()); 2650 genop_2(s, OP_GETMCNST, cursp(), sym); 2459 2651 push(); 2460 genop(s, MKOP_ABx(OP_STRING, cursp(), off)); 2652 genop_2(s, OP_STRING, cursp(), off); 2653 push(); 2461 2654 if (p2 || p3) { 2655 if (p2) { /* opt */ 2656 off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); 2657 genop_2(s, OP_STRING, cursp(), off); 2658 } 2659 else { 2660 genop_1(s, OP_LOADNIL, cursp()); 2661 } 2462 2662 push(); 2463 if (p2) {2464 off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));2465 genop(s, MKOP_ABx(OP_STRING, cursp(), off));2466 }2467 else {2468 genop(s, MKOP_A(OP_LOADNIL, cursp()));2469 }2470 2663 argc++; 2471 if (p3) { 2664 if (p3) { /* enc */ 2665 off = new_lit(s, mrb_str_new(s->mrb, p3, 1)); 2666 genop_2(s, OP_STRING, cursp(), off); 2472 2667 push(); 2473 off = new_lit(s, mrb_str_new(s->mrb, p3, 1));2474 genop(s, MKOP_ABx(OP_STRING, cursp(), off));2475 2668 argc++; 2476 pop(); 2477 } 2478 pop(); 2479 } 2480 pop(); 2669 } 2670 } 2671 push(); /* space for a block */ 2672 pop_n(argc+2); 2481 2673 sym = new_sym(s, mrb_intern_lit(s->mrb, "compile")); 2482 genop (s, MKOP_ABC(OP_SEND, cursp(), sym, argc));2674 genop_3(s, OP_SEND, cursp(), sym, argc); 2483 2675 mrb_gc_arena_restore(s->mrb, ai); 2484 2676 push(); … … 2495 2687 char *p; 2496 2688 2497 genop (s, MKOP_A(OP_OCLASS, cursp()));2498 genop (s, MKOP_ABx(OP_GETMCNST, cursp(), sym));2689 genop_1(s, OP_OCLASS, cursp()); 2690 genop_2(s, OP_GETMCNST, cursp(), sym); 2499 2691 push(); 2500 2692 codegen(s, n->car, VAL); … … 2503 2695 codegen(s, n->car, VAL); 2504 2696 pop(); pop(); 2505 genop_ peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);2697 genop_1(s, OP_STRCAT, cursp()); 2506 2698 push(); 2507 2699 n = n->cdr; 2508 2700 } 2509 2701 n = tree->cdr->cdr; 2510 if (n->car) { 2702 if (n->car) { /* tail */ 2511 2703 p = (char*)n->car; 2512 2704 off = new_lit(s, mrb_str_new_cstr(s->mrb, p)); 2513 2705 codegen(s, tree->car, VAL); 2514 genop (s, MKOP_ABx(OP_STRING, cursp(), off));2706 genop_2(s, OP_STRING, cursp(), off); 2515 2707 pop(); 2516 genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL); 2517 } 2518 if (n->cdr->car) { 2708 genop_1(s, OP_STRCAT, cursp()); 2709 push(); 2710 } 2711 if (n->cdr->car) { /* opt */ 2519 2712 char *p2 = (char*)n->cdr->car; 2520 2713 off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); 2714 genop_2(s, OP_STRING, cursp(), off); 2521 2715 push(); 2716 argc++; 2717 } 2718 if (n->cdr->cdr) { /* enc */ 2719 char *p2 = (char*)n->cdr->cdr; 2522 2720 off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); 2523 genop(s, MKOP_ABx(OP_STRING, cursp(), off)); 2721 genop_2(s, OP_STRING, cursp(), off); 2722 push(); 2524 2723 argc++; 2525 2724 } 2526 if (n->cdr->cdr) { 2527 char *p2 = (char*)n->cdr->cdr; 2528 2529 push(); 2530 off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); 2531 genop(s, MKOP_ABx(OP_STRING, cursp(), off)); 2532 argc++; 2533 } 2534 pop_n(argc); 2725 push(); /* space for a block */ 2726 pop_n(argc+2); 2535 2727 sym = new_sym(s, mrb_intern_lit(s->mrb, "compile")); 2536 genop (s, MKOP_ABC(OP_SEND, cursp(), sym, argc));2728 genop_3(s, OP_SEND, cursp(), sym, argc); 2537 2729 mrb_gc_arena_restore(s->mrb, ai); 2538 2730 push(); … … 2542 2734 2543 2735 while (n) { 2544 if ( (intptr_t)n->car->car!= NODE_STR) {2736 if (nint(n->car->car) != NODE_STR) { 2545 2737 codegen(s, n->car, NOVAL); 2546 2738 } … … 2552 2744 case NODE_SYM: 2553 2745 if (val) { 2554 int sym = new_sym(s, sym(tree));2555 2556 genop (s, MKOP_ABx(OP_LOADSYM, cursp(), sym));2746 int sym = new_sym(s, nsym(tree)); 2747 2748 genop_2(s, OP_LOADSYM, cursp(), sym); 2557 2749 push(); 2558 2750 } … … 2562 2754 codegen(s, tree, val); 2563 2755 if (val) { 2564 gen_ send_intern(s);2756 gen_intern(s); 2565 2757 } 2566 2758 break; … … 2568 2760 case NODE_SELF: 2569 2761 if (val) { 2570 genop (s, MKOP_A(OP_LOADSELF, cursp()));2762 genop_1(s, OP_LOADSELF, cursp()); 2571 2763 push(); 2572 2764 } … … 2575 2767 case NODE_NIL: 2576 2768 if (val) { 2577 genop (s, MKOP_A(OP_LOADNIL, cursp()));2769 genop_1(s, OP_LOADNIL, cursp()); 2578 2770 push(); 2579 2771 } … … 2582 2774 case NODE_TRUE: 2583 2775 if (val) { 2584 genop (s, MKOP_A(OP_LOADT, cursp()));2776 genop_1(s, OP_LOADT, cursp()); 2585 2777 push(); 2586 2778 } … … 2589 2781 case NODE_FALSE: 2590 2782 if (val) { 2591 genop (s, MKOP_A(OP_LOADF, cursp()));2783 genop_1(s, OP_LOADF, cursp()); 2592 2784 push(); 2593 2785 } … … 2596 2788 case NODE_ALIAS: 2597 2789 { 2598 int a = new_msym(s, sym(tree->car)); 2599 int b = new_msym(s, sym(tree->cdr)); 2600 int c = new_msym(s, mrb_intern_lit(s->mrb, "alias_method")); 2601 2602 genop(s, MKOP_A(OP_TCLASS, cursp())); 2603 push(); 2604 genop(s, MKOP_ABx(OP_LOADSYM, cursp(), a)); 2605 push(); 2606 genop(s, MKOP_ABx(OP_LOADSYM, cursp(), b)); 2607 push(); 2608 genop(s, MKOP_A(OP_LOADNIL, cursp())); 2609 push(); 2610 pop_n(4); 2611 genop(s, MKOP_ABC(OP_SEND, cursp(), c, 2)); 2790 int a = new_sym(s, nsym(tree->car)); 2791 int b = new_sym(s, nsym(tree->cdr)); 2792 2793 genop_2(s, OP_ALIAS, a, b); 2612 2794 if (val) { 2795 genop_1(s, OP_LOADNIL, cursp()); 2613 2796 push(); 2614 2797 } … … 2618 2801 case NODE_UNDEF: 2619 2802 { 2620 int undef = new_msym(s, mrb_intern_lit(s->mrb, "undef_method"));2621 int num = 0;2622 2803 node *t = tree; 2623 2804 2624 genop(s, MKOP_A(OP_TCLASS, cursp()));2625 push();2626 2805 while (t) { 2627 int symbol; 2628 if (num >= CALL_MAXARGS - 1) { 2629 pop_n(num); 2630 genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), num)); 2631 while (t) { 2632 symbol = new_msym(s, sym(t->car)); 2633 push(); 2634 genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol)); 2635 pop(); 2636 genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1)); 2637 t = t->cdr; 2638 } 2639 num = CALL_MAXARGS; 2640 break; 2641 } 2642 symbol = new_msym(s, sym(t->car)); 2643 genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol)); 2644 push(); 2806 int symbol = new_sym(s, nsym(t->car)); 2807 genop_1(s, OP_UNDEF, symbol); 2645 2808 t = t->cdr; 2646 num++; 2647 } 2648 pop(); 2649 if (num < CALL_MAXARGS) { 2650 pop_n(num); 2651 } 2652 genop(s, MKOP_ABC(OP_SEND, cursp(), undef, num)); 2809 } 2653 2810 if (val) { 2811 genop_1(s, OP_LOADNIL, cursp()); 2654 2812 push(); 2655 2813 } … … 2660 2818 { 2661 2819 int idx; 2820 node *body; 2662 2821 2663 2822 if (tree->car->car == (node*)0) { 2664 genop (s, MKOP_A(OP_LOADNIL, cursp()));2823 genop_1(s, OP_LOADNIL, cursp()); 2665 2824 push(); 2666 2825 } 2667 2826 else if (tree->car->car == (node*)1) { 2668 genop (s, MKOP_A(OP_OCLASS, cursp()));2827 genop_1(s, OP_OCLASS, cursp()); 2669 2828 push(); 2670 2829 } … … 2676 2835 } 2677 2836 else { 2678 genop (s, MKOP_A(OP_LOADNIL, cursp()));2837 genop_1(s, OP_LOADNIL, cursp()); 2679 2838 push(); 2680 2839 } 2681 2840 pop(); pop(); 2682 idx = new_msym(s, sym(tree->car->cdr)); 2683 genop(s, MKOP_AB(OP_CLASS, cursp(), idx)); 2684 idx = scope_body(s, tree->cdr->cdr->car, val); 2685 genop(s, MKOP_ABx(OP_EXEC, cursp(), idx)); 2841 idx = new_sym(s, nsym(tree->car->cdr)); 2842 genop_2(s, OP_CLASS, cursp(), idx); 2843 body = tree->cdr->cdr->car; 2844 if (nint(body->cdr->car) == NODE_BEGIN && body->cdr->cdr == NULL) { 2845 genop_1(s, OP_LOADNIL, cursp()); 2846 } 2847 else { 2848 idx = scope_body(s, body, val); 2849 genop_2(s, OP_EXEC, cursp(), idx); 2850 } 2686 2851 if (val) { 2687 2852 push(); … … 2695 2860 2696 2861 if (tree->car->car == (node*)0) { 2697 genop (s, MKOP_A(OP_LOADNIL, cursp()));2862 genop_1(s, OP_LOADNIL, cursp()); 2698 2863 push(); 2699 2864 } 2700 2865 else if (tree->car->car == (node*)1) { 2701 genop (s, MKOP_A(OP_OCLASS, cursp()));2866 genop_1(s, OP_OCLASS, cursp()); 2702 2867 push(); 2703 2868 } … … 2706 2871 } 2707 2872 pop(); 2708 idx = new_msym(s, sym(tree->car->cdr)); 2709 genop(s, MKOP_AB(OP_MODULE, cursp(), idx)); 2710 idx = scope_body(s, tree->cdr->car, val); 2711 genop(s, MKOP_ABx(OP_EXEC, cursp(), idx)); 2873 idx = new_sym(s, nsym(tree->car->cdr)); 2874 genop_2(s, OP_MODULE, cursp(), idx); 2875 if (nint(tree->cdr->car->cdr->car) == NODE_BEGIN && 2876 tree->cdr->car->cdr->cdr == NULL) { 2877 genop_1(s, OP_LOADNIL, cursp()); 2878 } 2879 else { 2880 idx = scope_body(s, tree->cdr->car, val); 2881 genop_2(s, OP_EXEC, cursp(), idx); 2882 } 2712 2883 if (val) { 2713 2884 push(); … … 2722 2893 codegen(s, tree->car, VAL); 2723 2894 pop(); 2724 genop(s, MKOP_AB(OP_SCLASS, cursp(), cursp())); 2725 idx = scope_body(s, tree->cdr->car, val); 2726 genop(s, MKOP_ABx(OP_EXEC, cursp(), idx)); 2895 genop_1(s, OP_SCLASS, cursp()); 2896 if (nint(tree->cdr->car->cdr->car) == NODE_BEGIN && 2897 tree->cdr->car->cdr->cdr == NULL) { 2898 genop_1(s, OP_LOADNIL, cursp()); 2899 } 2900 else { 2901 idx = scope_body(s, tree->cdr->car, val); 2902 genop_2(s, OP_EXEC, cursp(), idx); 2903 } 2727 2904 if (val) { 2728 2905 push(); … … 2733 2910 case NODE_DEF: 2734 2911 { 2735 int sym = new_ msym(s,sym(tree->car));2912 int sym = new_sym(s, nsym(tree->car)); 2736 2913 int idx = lambda_body(s, tree->cdr, 0); 2737 2914 2738 genop (s, MKOP_A(OP_TCLASS, cursp()));2915 genop_1(s, OP_TCLASS, cursp()); 2739 2916 push(); 2740 genop (s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_METHOD));2917 genop_2(s, OP_METHOD, cursp(), idx); 2741 2918 push(); pop(); 2742 2919 pop(); 2743 genop (s, MKOP_AB(OP_METHOD, cursp(), sym));2920 genop_2(s, OP_DEF, cursp(), sym); 2744 2921 if (val) { 2745 genop (s, MKOP_ABx(OP_LOADSYM, cursp(), sym));2922 genop_2(s, OP_LOADSYM, cursp(), sym); 2746 2923 push(); 2747 2924 } … … 2752 2929 { 2753 2930 node *recv = tree->car; 2754 int sym = new_ msym(s,sym(tree->cdr->car));2931 int sym = new_sym(s, nsym(tree->cdr->car)); 2755 2932 int idx = lambda_body(s, tree->cdr->cdr, 0); 2756 2933 2757 2934 codegen(s, recv, VAL); 2758 2935 pop(); 2759 genop (s, MKOP_AB(OP_SCLASS, cursp(), cursp()));2936 genop_1(s, OP_SCLASS, cursp()); 2760 2937 push(); 2761 genop (s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_METHOD));2938 genop_2(s, OP_METHOD, cursp(), idx); 2762 2939 pop(); 2763 genop (s, MKOP_AB(OP_METHOD, cursp(), sym));2940 genop_2(s, OP_DEF, cursp(), sym); 2764 2941 if (val) { 2765 genop (s, MKOP_ABx(OP_LOADSYM, cursp(), sym));2942 genop_2(s, OP_LOADSYM, cursp(), sym); 2766 2943 push(); 2767 2944 } … … 2802 2979 codegen_scope *p = (codegen_scope *)mrb_pool_alloc(pool, sizeof(codegen_scope)); 2803 2980 2804 if (!p) return NULL; 2981 if (!p) { 2982 if (prev) 2983 codegen_error(prev, "unexpected scope"); 2984 return NULL; 2985 } 2805 2986 *p = codegen_scope_zero; 2806 2987 p->mrb = mrb; … … 2825 3006 p->irep->plen = 0; 2826 3007 2827 p->scapa = MAXMSYMLEN;3008 p->scapa = 256; 2828 3009 p->irep->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*p->scapa); 2829 3010 p->irep->slen = 0; … … 2850 3031 p->ai = mrb_gc_arena_save(mrb); 2851 3032 2852 p->filename = prev->filename;2853 if (p->filename ) {3033 p->filename_sym = prev->filename_sym; 3034 if (p->filename_sym) { 2854 3035 p->lines = (uint16_t*)mrb_malloc(mrb, sizeof(short)*p->icapa); 2855 3036 } … … 2858 3039 /* debug setting */ 2859 3040 p->debug_start_pos = 0; 2860 if (p->filename ) {3041 if (p->filename_sym) { 2861 3042 mrb_debug_info_alloc(mrb, p->irep); 2862 p->irep->filename = p->filename;2863 p->irep->lines = p->lines;2864 3043 } 2865 3044 else { … … 2879 3058 mrb_state *mrb = s->mrb; 2880 3059 mrb_irep *irep = s->irep; 2881 size_t fname_len; 2882 char *fname; 2883 3060 3061 if (s->nlocals >= 0x3ff) { 3062 codegen_error(s, "too many local variables"); 3063 } 2884 3064 irep->flags = 0; 2885 3065 if (s->iseq) { 2886 3066 irep->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->pc); 2887 3067 irep->ilen = s->pc; 2888 if (s->lines) {2889 irep->lines = (uint16_t *)codegen_realloc(s, s->lines, sizeof(uint16_t)*s->pc);2890 }2891 else {2892 irep->lines = 0;2893 }2894 3068 } 2895 3069 irep->pool = (mrb_value*)codegen_realloc(s, irep->pool, sizeof(mrb_value)*irep->plen); 2896 3070 irep->syms = (mrb_sym*)codegen_realloc(s, irep->syms, sizeof(mrb_sym)*irep->slen); 2897 3071 irep->reps = (mrb_irep**)codegen_realloc(s, irep->reps, sizeof(mrb_irep*)*irep->rlen); 2898 if (s->filename) { 2899 irep->filename = mrb_parser_get_filename(s->parser, s->filename_index); 2900 mrb_debug_info_append_file(mrb, irep, s->debug_start_pos, s->pc); 2901 2902 fname_len = strlen(s->filename); 2903 fname = (char*)codegen_malloc(s, fname_len + 1); 2904 memcpy(fname, s->filename, fname_len); 2905 fname[fname_len] = '\0'; 2906 irep->filename = fname; 2907 irep->own_filename = TRUE; 2908 } 3072 if (s->filename_sym) { 3073 mrb_sym fname = mrb_parser_get_filename(s->parser, s->filename_index); 3074 const char *filename = mrb_sym_name_len(s->mrb, fname, NULL); 3075 3076 mrb_debug_info_append_file(s->mrb, s->irep->debug_info, 3077 filename, s->lines, s->debug_start_pos, s->pc); 3078 } 3079 mrb_free(s->mrb, s->lines); 2909 3080 2910 3081 irep->nlocals = s->nlocals; … … 2921 3092 2922 3093 p->type = t; 2923 p->pc 1 = p->pc2 = p->pc3 = 0;3094 p->pc0 = p->pc1 = p->pc2 = p->pc3 = 0; 2924 3095 p->prev = s->loop; 2925 3096 p->ensure_level = s->ensure_level; … … 2939 3110 else { 2940 3111 struct loopinfo *loop; 3112 int n = 0; 2941 3113 2942 3114 if (tree) { … … 2945 3117 2946 3118 loop = s->loop; 2947 while (loop && loop->type == LOOP_BEGIN) { 2948 genop_peep(s, MKOP_A(OP_POPERR, 1), NOVAL); 2949 loop = loop->prev; 2950 } 2951 while (loop && loop->type == LOOP_RESCUE) { 2952 loop = loop->prev; 3119 while (loop) { 3120 if (loop->type == LOOP_BEGIN) { 3121 n++; 3122 loop = loop->prev; 3123 } 3124 else if (loop->type == LOOP_RESCUE) { 3125 loop = loop->prev; 3126 } 3127 else{ 3128 break; 3129 } 2953 3130 } 2954 3131 if (!loop) { … … 2956 3133 return; 2957 3134 } 3135 if (n > 0) { 3136 genop_1(s, OP_POPERR, n); 3137 } 2958 3138 2959 3139 if (loop->type == LOOP_NORMAL) { … … 2961 3141 2962 3142 if (s->ensure_level > s->loop->ensure_level) { 2963 genop_ peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);3143 genop_1(s, OP_EPOP, s->ensure_level - s->loop->ensure_level); 2964 3144 } 2965 3145 if (tree) { 2966 gen op_peep(s, MKOP_AB(OP_MOVE, loop->acc, cursp()), NOVAL);2967 } 2968 tmp = gen op(s, MKOP_sBx(OP_JMP, loop->pc3));3146 gen_move(s, loop->acc, cursp(), 0); 3147 } 3148 tmp = genjmp(s, OP_JMP, loop->pc3); 2969 3149 loop->pc3 = tmp; 2970 3150 } 2971 3151 else { 2972 3152 if (!tree) { 2973 genop (s, MKOP_A(OP_LOADNIL, cursp()));2974 } 2975 gen op(s, MKOP_AB(OP_RETURN, cursp(), OP_R_BREAK));3153 genop_1(s, OP_LOADNIL, cursp()); 3154 } 3155 gen_return(s, OP_BREAK, cursp()); 2976 3156 } 2977 3157 } … … 2981 3161 loop_pop(codegen_scope *s, int val) 2982 3162 { 3163 if (val) { 3164 genop_1(s, OP_LOADNIL, cursp()); 3165 } 2983 3166 dispatch_linked(s, s->loop->pc3); 2984 if (val) {2985 genop(s, MKOP_A(OP_LOADNIL, cursp()));2986 }2987 3167 s->loop = s->loop->prev; 2988 3168 if (val) push(); 2989 3169 } 2990 3170 2991 MRB_APIstruct RProc*2992 mrb_generate_code(mrb_state *mrb, parser_state *p)3171 static struct RProc* 3172 generate_code(mrb_state *mrb, parser_state *p, int val) 2993 3173 { 2994 3174 codegen_scope *scope = scope_new(mrb, 0, 0); … … 2996 3176 struct mrb_jmpbuf *prev_jmp = mrb->jmp; 2997 3177 2998 if (!scope) {2999 return NULL;3000 }3001 3178 scope->mrb = mrb; 3002 3179 scope->parser = p; 3003 scope->filename = p->filename;3180 scope->filename_sym = p->filename_sym; 3004 3181 scope->filename_index = p->current_filename_index; 3005 3182 3006 3183 MRB_TRY(&scope->jmp) { 3007 mrb->jmp = &scope->jmp; 3184 mrb->jmp = &scope->jmp; 3008 3185 /* prepare irep */ 3009 codegen(scope, p->tree, NOVAL);3186 codegen(scope, p->tree, val); 3010 3187 proc = mrb_proc_new(mrb, scope->irep); 3011 3188 mrb_irep_decref(mrb, scope->irep); 3012 3189 mrb_pool_close(scope->mpool); 3013 3190 proc->c = NULL; 3191 if (mrb->c->cibase && mrb->c->cibase->proc == proc->upper) { 3192 proc->upper = NULL; 3193 } 3014 3194 mrb->jmp = prev_jmp; 3015 3195 return proc; … … 3023 3203 MRB_END_EXC(&scope->jmp); 3024 3204 } 3205 3206 MRB_API struct RProc* 3207 mrb_generate_code(mrb_state *mrb, parser_state *p) 3208 { 3209 return generate_code(mrb, p, VAL); 3210 } 3211 3212 void 3213 mrb_irep_remove_lv(mrb_state *mrb, mrb_irep *irep) 3214 { 3215 int i; 3216 3217 if (irep->lv) { 3218 mrb_free(mrb, irep->lv); 3219 irep->lv = NULL; 3220 } 3221 3222 for (i = 0; i < irep->rlen; ++i) { 3223 mrb_irep_remove_lv(mrb, irep->reps[i]); 3224 } 3225 } 3226 3227 #undef OPCODE 3228 #define Z 1 3229 #define S 3 3230 #define W 4 3231 /* instruction sizes */ 3232 uint8_t mrb_insn_size[] = { 3233 #define B 2 3234 #define BB 3 3235 #define BBB 4 3236 #define BS 4 3237 #define SB 4 3238 #define OPCODE(_,x) x, 3239 #include "mruby/ops.h" 3240 #undef OPCODE 3241 #undef B 3242 #undef BB 3243 #undef BS 3244 #undef SB 3245 #undef BBB 3246 }; 3247 /* EXT1 instruction sizes */ 3248 uint8_t mrb_insn_size1[] = { 3249 #define B 3 3250 #define BB 4 3251 #define BBB 5 3252 #define BS 5 3253 #define SB 5 3254 #define OPCODE(_,x) x, 3255 #include "mruby/ops.h" 3256 #undef OPCODE 3257 #undef B 3258 }; 3259 /* EXT2 instruction sizes */ 3260 uint8_t mrb_insn_size2[] = { 3261 #define B 2 3262 #define OPCODE(_,x) x, 3263 #include "mruby/ops.h" 3264 #undef OPCODE 3265 #undef BB 3266 #undef BBB 3267 #undef BS 3268 #undef SB 3269 }; 3270 /* EXT3 instruction sizes */ 3271 #define BB 5 3272 #define BBB 6 3273 #define BS 4 3274 #define SB 5 3275 uint8_t mrb_insn_size3[] = { 3276 #define OPCODE(_,x) x, 3277 #include "mruby/ops.h" 3278 }; -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-compiler/core/keywords
r270 r439 1 1 %{ 2 2 struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;}; 3 const struct kwtable *mrb_reserved_word(const char *, unsigned int);4 static const struct kwtable *reserved_word(const char *, unsigned int);5 #define mrb_reserved_word(str, len) reserved_word(str, len)6 3 %} 7 4 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-compiler/core/lex.def
r331 r439 1 /* ANSI-C code produced by gperf version 3. 0.4*/1 /* ANSI-C code produced by gperf version 3.1 */ 2 2 /* Command-line: gperf -L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k'1,3,$' /home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords */ 3 3 … … 26 26 && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) 27 27 /* The character set is not based on ISO-646. */ 28 #error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-g nu-gperf@gnu.org>."28 #error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gperf@gnu.org>." 29 29 #endif 30 30 … … 32 32 33 33 struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;}; 34 const struct kwtable *mrb_reserved_word(const char *, unsigned int); 35 static const struct kwtable *reserved_word(const char *, unsigned int); 36 #define mrb_reserved_word(str, len) reserved_word(str, len) 37 #line 8 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 34 #line 5 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 38 35 struct kwtable; 39 36 … … 53 50 #endif 54 51 static unsigned int 55 hash (register const char *str, register unsigned int len)52 hash (register const char *str, register size_t len) 56 53 { 57 54 static const unsigned char asso_values[] = … … 84 81 51, 51, 51, 51, 51, 51 85 82 }; 86 register int hval = len;83 register unsigned int hval = len; 87 84 88 85 switch (hval) … … 99 96 } 100 97 101 #ifdef __GNUC__102 __inline103 #if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__104 __attribute__ ((__gnu_inline__))105 #endif106 #endif107 98 const struct kwtable * 108 mrb_reserved_word (register const char *str, register unsigned int len)99 mrb_reserved_word (register const char *str, register size_t len) 109 100 { 110 101 static const struct kwtable wordlist[] = 111 102 { 112 103 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, 104 #line 15 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 105 {"break", {keyword_break, keyword_break}, EXPR_MID}, 106 #line 20 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 107 {"else", {keyword_else, keyword_else}, EXPR_BEG}, 108 #line 30 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 109 {"nil", {keyword_nil, keyword_nil}, EXPR_END}, 110 #line 23 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 111 {"ensure", {keyword_ensure, keyword_ensure}, EXPR_BEG}, 112 #line 22 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 113 {"end", {keyword_end, keyword_end}, EXPR_END}, 114 #line 39 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 115 {"then", {keyword_then, keyword_then}, EXPR_BEG}, 116 #line 31 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 117 {"not", {keyword_not, keyword_not}, EXPR_ARG}, 118 #line 24 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 119 {"false", {keyword_false, keyword_false}, EXPR_END}, 120 #line 37 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 121 {"self", {keyword_self, keyword_self}, EXPR_END}, 122 #line 21 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 123 {"elsif", {keyword_elsif, keyword_elsif}, EXPR_VALUE}, 124 #line 34 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 125 {"rescue", {keyword_rescue, modifier_rescue}, EXPR_MID}, 126 #line 40 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 127 {"true", {keyword_true, keyword_true}, EXPR_END}, 128 #line 43 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 129 {"until", {keyword_until, modifier_until}, EXPR_VALUE}, 130 #line 42 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 131 {"unless", {keyword_unless, modifier_unless}, EXPR_VALUE}, 132 #line 36 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 133 {"return", {keyword_return, keyword_return}, EXPR_MID}, 113 134 #line 18 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 114 {"break", {keyword_break, keyword_break}, EXPR_MID}, 115 #line 23 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 116 {"else", {keyword_else, keyword_else}, EXPR_BEG}, 135 {"def", {keyword_def, keyword_def}, EXPR_FNAME}, 136 #line 13 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 137 {"and", {keyword_and, keyword_and}, EXPR_VALUE}, 138 #line 19 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 139 {"do", {keyword_do, keyword_do}, EXPR_BEG}, 140 #line 46 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 141 {"yield", {keyword_yield, keyword_yield}, EXPR_ARG}, 142 #line 25 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 143 {"for", {keyword_for, keyword_for}, EXPR_VALUE}, 144 #line 41 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 145 {"undef", {keyword_undef, keyword_undef}, EXPR_FNAME}, 146 #line 32 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 147 {"or", {keyword_or, keyword_or}, EXPR_VALUE}, 148 #line 27 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 149 {"in", {keyword_in, keyword_in}, EXPR_VALUE}, 150 #line 44 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 151 {"when", {keyword_when, keyword_when}, EXPR_VALUE}, 152 #line 35 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 153 {"retry", {keyword_retry, keyword_retry}, EXPR_END}, 154 #line 26 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 155 {"if", {keyword_if, modifier_if}, EXPR_VALUE}, 156 #line 16 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 157 {"case", {keyword_case, keyword_case}, EXPR_VALUE}, 117 158 #line 33 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 118 {"nil", {keyword_nil, keyword_nil}, EXPR_END}, 119 #line 26 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 120 {"ensure", {keyword_ensure, keyword_ensure}, EXPR_BEG}, 121 #line 25 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 122 {"end", {keyword_end, keyword_end}, EXPR_END}, 123 #line 42 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 124 {"then", {keyword_then, keyword_then}, EXPR_BEG}, 125 #line 34 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 126 {"not", {keyword_not, keyword_not}, EXPR_ARG}, 127 #line 27 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 128 {"false", {keyword_false, keyword_false}, EXPR_END}, 129 #line 40 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 130 {"self", {keyword_self, keyword_self}, EXPR_END}, 131 #line 24 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 132 {"elsif", {keyword_elsif, keyword_elsif}, EXPR_VALUE}, 133 #line 37 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 134 {"rescue", {keyword_rescue, modifier_rescue}, EXPR_MID}, 135 #line 43 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 136 {"true", {keyword_true, keyword_true}, EXPR_END}, 137 #line 46 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 138 {"until", {keyword_until, modifier_until}, EXPR_VALUE}, 139 #line 45 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 140 {"unless", {keyword_unless, modifier_unless}, EXPR_VALUE}, 141 #line 39 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 142 {"return", {keyword_return, keyword_return}, EXPR_MID}, 143 #line 21 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 144 {"def", {keyword_def, keyword_def}, EXPR_FNAME}, 145 #line 16 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 146 {"and", {keyword_and, keyword_and}, EXPR_VALUE}, 147 #line 22 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 148 {"do", {keyword_do, keyword_do}, EXPR_BEG}, 149 #line 49 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 150 {"yield", {keyword_yield, keyword_yield}, EXPR_ARG}, 159 {"redo", {keyword_redo, keyword_redo}, EXPR_END}, 160 #line 29 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 161 {"next", {keyword_next, keyword_next}, EXPR_MID}, 162 #line 38 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 163 {"super", {keyword_super, keyword_super}, EXPR_ARG}, 151 164 #line 28 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 152 {"for", {keyword_for, keyword_for}, EXPR_VALUE},153 #line 44 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"154 {"undef", {keyword_undef, keyword_undef}, EXPR_FNAME},155 #line 35 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"156 {"or", {keyword_or, keyword_or}, EXPR_VALUE},157 #line 30 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"158 {"in", {keyword_in, keyword_in}, EXPR_VALUE},159 #line 47 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"160 {"when", {keyword_when, keyword_when}, EXPR_VALUE},161 #line 38 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"162 {"retry", {keyword_retry, keyword_retry}, EXPR_END},163 #line 29 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"164 {"if", {keyword_if, modifier_if}, EXPR_VALUE},165 #line 19 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"166 {"case", {keyword_case, keyword_case}, EXPR_VALUE},167 #line 36 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"168 {"redo", {keyword_redo, keyword_redo}, EXPR_END},169 #line 32 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"170 {"next", {keyword_next, keyword_next}, EXPR_MID},171 #line 41 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"172 {"super", {keyword_super, keyword_super}, EXPR_ARG},173 #line 31 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"174 165 {"module", {keyword_module, keyword_module}, EXPR_VALUE}, 175 #line 1 7"/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"166 #line 14 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 176 167 {"begin", {keyword_begin, keyword_begin}, EXPR_BEG}, 168 #line 9 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 169 {"__LINE__", {keyword__LINE__, keyword__LINE__}, EXPR_END}, 170 #line 8 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 171 {"__FILE__", {keyword__FILE__, keyword__FILE__}, EXPR_END}, 172 #line 7 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 173 {"__ENCODING__", {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END}, 174 #line 11 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 175 {"END", {keyword_END, keyword_END}, EXPR_END}, 177 176 #line 12 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 178 {"__LINE__", {keyword__LINE__, keyword__LINE__}, EXPR_END}, 179 #line 11 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 180 {"__FILE__", {keyword__FILE__, keyword__FILE__}, EXPR_END}, 177 {"alias", {keyword_alias, keyword_alias}, EXPR_FNAME}, 181 178 #line 10 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 182 {"__ENCODING__", {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END},183 #line 14 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"184 {"END", {keyword_END, keyword_END}, EXPR_END},185 #line 15 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"186 {"alias", {keyword_alias, keyword_alias}, EXPR_FNAME},187 #line 13 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"188 179 {"BEGIN", {keyword_BEGIN, keyword_BEGIN}, EXPR_END}, 189 180 {""}, 190 #line 20"/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"181 #line 17 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 191 182 {"class", {keyword_class, keyword_class}, EXPR_CLASS}, 192 183 {""}, {""}, 193 #line 4 8"/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"184 #line 45 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 194 185 {"while", {keyword_while, modifier_while}, EXPR_VALUE} 195 186 }; … … 197 188 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) 198 189 { 199 register int key = hash (str, len);200 201 if (key <= MAX_HASH_VALUE && key >= 0)190 register unsigned int key = hash (str, len); 191 192 if (key <= MAX_HASH_VALUE) 202 193 { 203 194 register const char *s = wordlist[key].name; … … 209 200 return 0; 210 201 } 211 #line 50"/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"212 202 #line 47 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" 203 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-compiler/core/node.h
r331 r439 10 10 enum node_type { 11 11 NODE_METHOD, 12 NODE_FBODY,13 NODE_CFUNC,14 12 NODE_SCOPE, 15 13 NODE_BLOCK, … … 17 15 NODE_CASE, 18 16 NODE_WHEN, 19 NODE_OPT_N,20 17 NODE_WHILE, 21 18 NODE_UNTIL, … … 41 38 NODE_SCALL, 42 39 NODE_FCALL, 43 NODE_VCALL,44 40 NODE_SUPER, 45 41 NODE_ZSUPER, … … 47 43 NODE_ZARRAY, 48 44 NODE_HASH, 45 NODE_KW_HASH, 49 46 NODE_RETURN, 50 47 NODE_YIELD, … … 55 52 NODE_CONST, 56 53 NODE_CVAR, 54 NODE_NVAR, 57 55 NODE_NTH_REF, 58 56 NODE_BACK_REF, 59 57 NODE_MATCH, 60 NODE_MATCH2,61 NODE_MATCH3,62 58 NODE_INT, 63 59 NODE_FLOAT, … … 72 68 NODE_DREGX, 73 69 NODE_DREGX_ONCE, 74 NODE_LIST,75 70 NODE_ARG, 76 NODE_ARGSCAT, 77 NODE_ARGSPUSH, 71 NODE_ARGS_TAIL, 72 NODE_KW_ARG, 73 NODE_KW_REST_ARGS, 78 74 NODE_SPLAT, 79 75 NODE_TO_ARY, … … 89 85 NODE_COLON2, 90 86 NODE_COLON3, 91 NODE_CREF,92 87 NODE_DOT2, 93 88 NODE_DOT3, 94 NODE_FLIP2,95 NODE_FLIP3,96 NODE_ATTRSET,97 89 NODE_SELF, 98 90 NODE_NIL, … … 100 92 NODE_FALSE, 101 93 NODE_DEFINED, 102 NODE_NEWLINE,103 94 NODE_POSTEXE, 104 NODE_ALLOCA,105 NODE_DMETHOD,106 NODE_BMETHOD,107 NODE_MEMO,108 NODE_IFUNC,109 95 NODE_DSYM, 110 NODE_ATTRASGN,111 96 NODE_HEREDOC, 112 97 NODE_LITERAL_DELIM, -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-compiler/core/parse.y
r331 r439 11 11 #endif 12 12 #define YYERROR_VERBOSE 1 13 /* 14 * Force yacc to use our memory management. This is a little evil because 15 * the macros assume that "parser_state *p" is in scope 16 */ 17 #define YYMALLOC(n) mrb_malloc(p->mrb, (n)) 18 #define YYFREE(o) mrb_free(p->mrb, (o)) 19 #define YYSTACK_USE_ALLOCA 0 13 #define YYSTACK_USE_ALLOCA 1 20 14 21 15 #include <ctype.h> … … 28 22 #include <mruby/error.h> 29 23 #include <mruby/throw.h> 24 #include <mruby/string.h> 30 25 #include "node.h" 31 26 … … 77 72 #define intn(x) ((int)(intptr_t)(x)) 78 73 74 #define NUM_SUFFIX_R (1<<0) 75 #define NUM_SUFFIX_I (1<<1) 76 79 77 static inline mrb_sym 80 78 intern_cstr_gen(parser_state *p, const char *s) … … 91 89 #define intern(s,len) intern_gen(p,(s),(len)) 92 90 93 static inline mrb_sym 94 intern_gen_c(parser_state *p, const char c) 95 { 96 return mrb_intern(p->mrb, &c, 1); 97 } 98 #define intern_c(c) intern_gen_c(p,(c)) 91 #define intern_lit(s) mrb_intern_lit(p->mrb, s) 99 92 100 93 static void … … 134 127 c->lineno = p->lineno; 135 128 c->filename_index = p->current_filename_index; 129 /* beginning of next partial file; need to point the previous file */ 130 if (p->lineno == 0 && p->current_filename_index > 0) { 131 c->filename_index-- ; 132 } 136 133 return c; 137 134 } … … 186 183 187 184 if (!a) return b; 185 if (!b) return a; 188 186 while (c->cdr) { 189 187 c = c->cdr; 190 188 } 191 if (b) { 192 c->cdr = b; 193 } 189 c->cdr = b; 194 190 return a; 195 191 } … … 216 212 #undef strdup 217 213 #define strdup(s) parser_strdup(p, s) 214 215 static void 216 dump_int(uint16_t i, char *s) 217 { 218 char *p = s; 219 char *t = s; 220 221 while (i > 0) { 222 *p++ = (i % 10)+'0'; 223 i /= 10; 224 } 225 if (p == s) *p++ = '0'; 226 *p = 0; 227 p--; /* point the last char */ 228 while (t < p) { 229 char c = *t; 230 *t++ = *p; 231 *p-- = c; 232 } 233 } 218 234 219 235 /* xxx ----------------------------- */ … … 280 296 } 281 297 298 static void 299 local_add_blk(parser_state *p, mrb_sym blk) 300 { 301 /* allocate register for block */ 302 local_add_f(p, blk ? blk : mrb_intern_lit(p->mrb, "&")); 303 } 304 305 static void 306 local_add_kw(parser_state *p, mrb_sym kwd) 307 { 308 /* allocate register for keywords hash */ 309 local_add_f(p, kwd ? kwd : mrb_intern_lit(p->mrb, "**")); 310 } 311 282 312 static node* 283 313 locals_node(parser_state *p) 284 314 { 285 315 return p->locals ? p->locals->car : NULL; 316 } 317 318 static void 319 nvars_nest(parser_state *p) 320 { 321 p->nvars = cons(nint(0), p->nvars); 322 } 323 324 static void 325 nvars_block(parser_state *p) 326 { 327 p->nvars = cons(nint(-2), p->nvars); 328 } 329 330 static void 331 nvars_unnest(parser_state *p) 332 { 333 p->nvars = p->nvars->cdr; 286 334 } 287 335 … … 569 617 } 570 618 619 /* (:kw_hash (k . v) (k . v)...) */ 620 static node* 621 new_kw_hash(parser_state *p, node *a) 622 { 623 return cons((node*)NODE_KW_HASH, a); 624 } 625 571 626 /* (:sym . a) */ 572 627 static node* … … 613 668 } 614 669 670 /* (:nvar . a) */ 671 static node* 672 new_nvar(parser_state *p, int num) 673 { 674 int nvars = intn(p->nvars->car); 675 676 p->nvars->car = nint(nvars > num ? nvars : num); 677 return cons((node*)NODE_NVAR, nint(num)); 678 } 679 615 680 /* (:const . a) */ 616 681 static node* … … 672 737 } 673 738 674 /* (m o r m2 b) */ 739 static void 740 local_add_margs(parser_state *p, node *n) 741 { 742 while (n) { 743 if (n->car->car == (node*)NODE_MASGN) { 744 node *t = n->car->cdr->cdr; 745 746 n->car->cdr->cdr = NULL; 747 while (t) { 748 local_add_f(p, sym(t->car)); 749 t = t->cdr; 750 } 751 local_add_margs(p, n->car->cdr->car->car); 752 local_add_margs(p, n->car->cdr->car->cdr->cdr->car); 753 } 754 n = n->cdr; 755 } 756 } 757 758 static void 759 local_add_lv(parser_state *p, node *lv) 760 { 761 while (lv) { 762 local_add_f(p, sym(lv->car)); 763 lv = lv->cdr; 764 } 765 } 766 767 /* (m o r m2 tail) */ 675 768 /* m: (a b c) */ 676 769 /* o: ((a . e1) (b . e2)) */ … … 679 772 /* b: a */ 680 773 static node* 681 new_args(parser_state *p, node *m, node *opt, mrb_sym rest, node *m2, mrb_sym blk)774 new_args(parser_state *p, node *m, node *opt, mrb_sym rest, node *m2, node *tail) 682 775 { 683 776 node *n; 684 777 685 n = cons(m2, nsym(blk)); 778 local_add_margs(p, m); 779 local_add_margs(p, m2); 780 n = cons(m2, tail); 686 781 n = cons(nsym(rest), n); 687 782 n = cons(opt, n); 783 while (opt) { 784 /* opt: (sym . (opt . lv)) -> (sym . opt) */ 785 local_add_lv(p, opt->car->cdr->cdr); 786 opt->car->cdr = opt->car->cdr->car; 787 opt = opt->cdr; 788 } 688 789 return cons(m, n); 689 790 } 690 791 792 /* (:args_tail keywords rest_keywords_sym block_sym) */ 793 static node* 794 new_args_tail(parser_state *p, node *kws, node *kwrest, mrb_sym blk) 795 { 796 node *k; 797 798 if (kws || kwrest) { 799 local_add_kw(p, (kwrest && kwrest->cdr)? sym(kwrest->cdr) : 0); 800 } 801 802 local_add_blk(p, blk); 803 804 /* allocate register for keywords arguments */ 805 /* order is for Proc#parameters */ 806 for (k = kws; k; k = k->cdr) { 807 if (!k->car->cdr->cdr->car) { /* allocate required keywords */ 808 local_add_f(p, sym(k->car->cdr->car)); 809 } 810 } 811 for (k = kws; k; k = k->cdr) { 812 if (k->car->cdr->cdr->car) { /* allocate keywords with default */ 813 local_add_lv(p, k->car->cdr->cdr->car->cdr); 814 k->car->cdr->cdr->car = k->car->cdr->cdr->car->car; 815 local_add_f(p, sym(k->car->cdr->car)); 816 } 817 } 818 819 return list4((node*)NODE_ARGS_TAIL, kws, kwrest, nsym(blk)); 820 } 821 822 /* (:kw_arg kw_sym def_arg) */ 823 static node* 824 new_kw_arg(parser_state *p, mrb_sym kw, node *def_arg) 825 { 826 mrb_assert(kw); 827 return list3((node*)NODE_KW_ARG, nsym(kw), def_arg); 828 } 829 691 830 /* (:block_arg . a) */ 692 831 static node* … … 696 835 } 697 836 837 static node* 838 setup_numparams(parser_state *p, node *a) 839 { 840 int nvars = intn(p->nvars->car); 841 if (nvars > 0) { 842 int i; 843 mrb_sym sym; 844 // m || opt || rest || tail 845 if (a && (a->car || (a->cdr && a->cdr->car) || (a->cdr->cdr && a->cdr->cdr->car) || (a->cdr->cdr->cdr->cdr && a->cdr->cdr->cdr->cdr->car))) { 846 yyerror(p, "ordinary parameter is defined"); 847 } 848 else if (p->locals) { 849 /* p->locals should not be NULL unless error happens before the point */ 850 node* args = 0; 851 for (i = nvars; i > 0; i--) { 852 char buf[3]; 853 854 buf[0] = '_'; 855 buf[1] = i+'0'; 856 buf[2] = '\0'; 857 sym = intern_cstr(buf); 858 args = cons(new_arg(p, sym), args); 859 p->locals->car = cons(nsym(sym), p->locals->car); 860 } 861 a = new_args(p, args, 0, 0, 0, 0); 862 } 863 } 864 return a; 865 } 866 698 867 /* (:block arg body) */ 699 868 static node* 700 869 new_block(parser_state *p, node *a, node *b) 701 870 { 871 a = setup_numparams(p, a); 702 872 return list4((node*)NODE_BLOCK, locals_node(p), a, b); 703 873 } … … 726 896 } 727 897 898 /* (:masgn mlhs mrhs) no check */ 899 static node* 900 new_masgn_param(parser_state *p, node *a, node *b) 901 { 902 return cons((node*)NODE_MASGN, cons(a, b)); 903 } 904 728 905 /* (:asgn lhs rhs) */ 729 906 static node* … … 734 911 } 735 912 913 static node* 914 new_imaginary(parser_state *p, node *imaginary) 915 { 916 return new_call(p, new_const(p, intern_lit("Kernel")), intern_lit("Complex"), list1(list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary)), 1); 917 } 918 919 static node* 920 new_rational(parser_state *p, node *rational) 921 { 922 return new_call(p, new_const(p, intern_lit("Kernel")), intern_lit("Rational"), list1(list1(rational)), 1); 923 } 924 736 925 /* (:int . i) */ 737 926 static node* 738 new_int(parser_state *p, const char *s, int base) 739 { 740 return list3((node*)NODE_INT, (node*)strdup(s), nint(base)); 741 } 742 927 new_int(parser_state *p, const char *s, int base, int suffix) 928 { 929 node* result = list3((node*)NODE_INT, (node*)strdup(s), nint(base)); 930 if (suffix & NUM_SUFFIX_R) { 931 result = new_rational(p, result); 932 } 933 if (suffix & NUM_SUFFIX_I) { 934 result = new_imaginary(p, result); 935 } 936 return result; 937 } 938 939 #ifndef MRB_WITHOUT_FLOAT 743 940 /* (:float . i) */ 744 941 static node* 745 new_float(parser_state *p, const char *s) 746 { 747 return cons((node*)NODE_FLOAT, (node*)strdup(s)); 748 } 942 new_float(parser_state *p, const char *s, int suffix) 943 { 944 node* result = cons((node*)NODE_FLOAT, (node*)strdup(s)); 945 if (suffix & NUM_SUFFIX_R) { 946 result = new_rational(p, result); 947 } 948 if (suffix & NUM_SUFFIX_I) { 949 result = new_imaginary(p, result); 950 } 951 return result; 952 } 953 #endif 749 954 750 955 /* (:str . (s . len)) */ 751 956 static node* 752 new_str(parser_state *p, const char *s, int len)957 new_str(parser_state *p, const char *s, size_t len) 753 958 { 754 959 return cons((node*)NODE_STR, cons((node*)strndup(s, len), nint(len))); … … 762 967 } 763 968 969 static int 970 string_node_p(node *n) 971 { 972 return (int)((enum node_type)(intptr_t)n->car == NODE_STR); 973 } 974 975 static node* 976 composite_string_node(parser_state *p, node *a, node *b) 977 { 978 size_t newlen = (size_t)a->cdr + (size_t)b->cdr; 979 char *str = (char*)mrb_pool_realloc(p->pool, a->car, (size_t)a->cdr + 1, newlen + 1); 980 memcpy(str + (size_t)a->cdr, b->car, (size_t)b->cdr); 981 str[newlen] = '\0'; 982 a->car = (node*)str; 983 a->cdr = (node*)newlen; 984 cons_free(b); 985 return a; 986 } 987 988 static node* 989 concat_string(parser_state *p, node *a, node *b) 990 { 991 if (string_node_p(a)) { 992 if (string_node_p(b)) { 993 /* a == NODE_STR && b == NODE_STR */ 994 composite_string_node(p, a->cdr, b->cdr); 995 cons_free(b); 996 return a; 997 } 998 else { 999 /* a == NODE_STR && b == NODE_DSTR */ 1000 1001 if (string_node_p(b->cdr->car)) { 1002 /* a == NODE_STR && b->[NODE_STR, ...] */ 1003 composite_string_node(p, a->cdr, b->cdr->car->cdr); 1004 cons_free(b->cdr->car); 1005 b->cdr->car = a; 1006 return b; 1007 } 1008 } 1009 } 1010 else { 1011 node *c; /* last node of a */ 1012 for (c = a; c->cdr != NULL; c = c->cdr) ; 1013 1014 if (string_node_p(b)) { 1015 /* a == NODE_DSTR && b == NODE_STR */ 1016 if (string_node_p(c->car)) { 1017 /* a->[..., NODE_STR] && b == NODE_STR */ 1018 composite_string_node(p, c->car->cdr, b->cdr); 1019 cons_free(b); 1020 return a; 1021 } 1022 1023 push(a, b); 1024 return a; 1025 } 1026 else { 1027 /* a == NODE_DSTR && b == NODE_DSTR */ 1028 if (string_node_p(c->car) && string_node_p(b->cdr->car)) { 1029 /* a->[..., NODE_STR] && b->[NODE_STR, ...] */ 1030 node *d = b->cdr; 1031 cons_free(b); 1032 composite_string_node(p, c->car->cdr, d->car->cdr); 1033 cons_free(d->car); 1034 c->cdr = d->cdr; 1035 cons_free(d); 1036 return a; 1037 } 1038 else { 1039 c->cdr = b->cdr; 1040 cons_free(b); 1041 return a; 1042 } 1043 } 1044 } 1045 1046 return new_dstr(p, list2(a, b)); 1047 } 1048 764 1049 /* (:str . (s . len)) */ 765 1050 static node* … … 780 1065 new_dsym(parser_state *p, node *a) 781 1066 { 782 return cons((node*)NODE_DSYM, new_dstr(p, a));1067 return cons((node*)NODE_DSYM, a); 783 1068 } 784 1069 … … 1024 1309 if (p->parsing_heredoc == NULL) { 1025 1310 p->lstate = EXPR_BEG; 1026 p->cmd_start = TRUE;1027 1311 end_strterm(p); 1028 1312 p->lex_strterm = p->lex_strterm_before_heredoc; 1029 1313 p->lex_strterm_before_heredoc = NULL; 1030 p->heredoc_end_now = TRUE;1031 1314 } 1032 1315 else { … … 1105 1388 keyword__ENCODING__ 1106 1389 1107 %token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL 1390 %token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL_TAG 1108 1391 %token <nd> tINTEGER tFLOAT tCHAR tXSTRING tREGEXP 1109 %token <nd> tSTRING tSTRING_PART tSTRING_MID tLABEL_END1392 %token <nd> tSTRING tSTRING_PART tSTRING_MID 1110 1393 %token <nd> tNTH_REF tBACK_REF 1111 1394 %token <num> tREGEXP_END 1112 1113 %type <nd> singleton string string_rep string_interp xstring regexp 1395 %token <num> tNUMPARAM 1396 1397 %type <nd> singleton string string_fragment string_rep string_interp xstring regexp 1114 1398 %type <nd> literal numeric cpath symbol 1115 1399 %type <nd> top_compstmt top_stmts top_stmt … … 1122 1406 %type <nd> command_asgn command_rhs mrhs superclass block_call block_command 1123 1407 %type <nd> f_block_optarg f_block_opt 1124 %type <nd> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs1408 %type <nd> f_arglist f_args f_arg f_arg_item f_optarg f_margs 1125 1409 %type <nd> assoc_list assocs assoc undef_list backref for_var 1126 1410 %type <nd> block_param opt_block_param block_param_def f_opt … … 1132 1416 %type <nd> heredoc words symbols 1133 1417 %type <num> call_op call_op2 /* 0:'&.', 1:'.', 2:'::' */ 1418 1419 %type <nd> args_tail opt_args_tail f_kwarg f_kw f_kwrest 1420 %type <nd> f_block_kwarg f_block_kw block_args_tail opt_block_args_tail 1421 %type <id> f_label 1134 1422 1135 1423 %token tUPLUS /* unary+ */ … … 1158 1446 %token tLBRACE_ARG /* { */ 1159 1447 %token tSTAR /* * */ 1448 %token tDSTAR /* ** */ 1160 1449 %token tAMPER /* & */ 1161 1450 %token tLAMBDA /* -> */ … … 1179 1468 %right '=' tOP_ASGN 1180 1469 %left modifier_rescue 1181 %right '?' ':' 1470 %right '?' ':' tLABEL_TAG 1182 1471 %nonassoc tDOT2 tDOT3 1183 1472 %left tOROP … … 1237 1526 { 1238 1527 $<nd>$ = local_switch(p); 1528 nvars_block(p); 1239 1529 } 1240 1530 '{' top_compstmt '}' … … 1242 1532 yyerror(p, "BEGIN not supported"); 1243 1533 local_resume(p, $<nd>2); 1534 nvars_unnest(p); 1244 1535 $$ = 0; 1245 1536 } … … 1359 1650 $$ = new_op_asgn(p, $1, $2, $3); 1360 1651 } 1361 | primary_value '[' opt_call_args rbrackettOP_ASGN command_rhs1362 { 1363 $$ = new_op_asgn(p, new_call(p, $1, intern ("[]",2), $3, '.'), $5, $6);1652 | primary_value '[' opt_call_args ']' tOP_ASGN command_rhs 1653 { 1654 $$ = new_op_asgn(p, new_call(p, $1, intern_lit("[]"), $3, '.'), $5, $6); 1364 1655 } 1365 1656 | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs … … 1385 1676 $$ = new_begin(p, 0); 1386 1677 } 1387 1678 ; 1388 1679 1389 1680 command_rhs : command_call %prec tOP_ASGN … … 1439 1730 { 1440 1731 local_nest(p); 1732 nvars_nest(p); 1441 1733 } 1442 1734 opt_block_param … … 1446 1738 $$ = new_block(p, $3, $4); 1447 1739 local_unnest(p); 1740 nvars_unnest(p); 1448 1741 } 1449 1742 ; … … 1588 1881 assignable(p, $1); 1589 1882 } 1590 | primary_value '[' opt_call_args rbracket1591 { 1592 $$ = new_call(p, $1, intern ("[]",2), $3, '.');1883 | primary_value '[' opt_call_args ']' 1884 { 1885 $$ = new_call(p, $1, intern_lit("[]"), $3, '.'); 1593 1886 } 1594 1887 | primary_value call_op tIDENTIFIER … … 1627 1920 assignable(p, $1); 1628 1921 } 1629 | primary_value '[' opt_call_args rbracket1630 { 1631 $$ = new_call(p, $1, intern ("[]",2), $3, '.');1922 | primary_value '[' opt_call_args ']' 1923 { 1924 $$ = new_call(p, $1, intern_lit("[]"), $3, '.'); 1632 1925 } 1633 1926 | primary_value call_op tIDENTIFIER … … 1659 1952 backref_error(p, $1); 1660 1953 $$ = 0; 1954 } 1955 | tNUMPARAM 1956 { 1957 yyerror(p, "can't assign to numbered parameter"); 1661 1958 } 1662 1959 ; … … 1713 2010 ; 1714 2011 1715 op : '|' { $$ = intern_c('|'); } 1716 | '^' { $$ = intern_c('^'); } 1717 | '&' { $$ = intern_c('&'); } 1718 | tCMP { $$ = intern("<=>",3); } 1719 | tEQ { $$ = intern("==",2); } 1720 | tEQQ { $$ = intern("===",3); } 1721 | tMATCH { $$ = intern("=~",2); } 1722 | tNMATCH { $$ = intern("!~",2); } 1723 | '>' { $$ = intern_c('>'); } 1724 | tGEQ { $$ = intern(">=",2); } 1725 | '<' { $$ = intern_c('<'); } 1726 | tLEQ { $$ = intern("<=",2); } 1727 | tNEQ { $$ = intern("!=",2); } 1728 | tLSHFT { $$ = intern("<<",2); } 1729 | tRSHFT { $$ = intern(">>",2); } 1730 | '+' { $$ = intern_c('+'); } 1731 | '-' { $$ = intern_c('-'); } 1732 | '*' { $$ = intern_c('*'); } 1733 | tSTAR { $$ = intern_c('*'); } 1734 | '/' { $$ = intern_c('/'); } 1735 | '%' { $$ = intern_c('%'); } 1736 | tPOW { $$ = intern("**",2); } 1737 | '!' { $$ = intern_c('!'); } 1738 | '~' { $$ = intern_c('~'); } 1739 | tUPLUS { $$ = intern("+@",2); } 1740 | tUMINUS { $$ = intern("-@",2); } 1741 | tAREF { $$ = intern("[]",2); } 1742 | tASET { $$ = intern("[]=",3); } 1743 | '`' { $$ = intern_c('`'); } 2012 op : '|' { $$ = intern_lit("|"); } 2013 | '^' { $$ = intern_lit("^"); } 2014 | '&' { $$ = intern_lit("&"); } 2015 | tCMP { $$ = intern_lit("<=>"); } 2016 | tEQ { $$ = intern_lit("=="); } 2017 | tEQQ { $$ = intern_lit("==="); } 2018 | tMATCH { $$ = intern_lit("=~"); } 2019 | tNMATCH { $$ = intern_lit("!~"); } 2020 | '>' { $$ = intern_lit(">"); } 2021 | tGEQ { $$ = intern_lit(">="); } 2022 | '<' { $$ = intern_lit("<"); } 2023 | tLEQ { $$ = intern_lit("<="); } 2024 | tNEQ { $$ = intern_lit("!="); } 2025 | tLSHFT { $$ = intern_lit("<<"); } 2026 | tRSHFT { $$ = intern_lit(">>"); } 2027 | '+' { $$ = intern_lit("+"); } 2028 | '-' { $$ = intern_lit("-"); } 2029 | '*' { $$ = intern_lit("*"); } 2030 | tSTAR { $$ = intern_lit("*"); } 2031 | '/' { $$ = intern_lit("/"); } 2032 | '%' { $$ = intern_lit("%"); } 2033 | tPOW { $$ = intern_lit("**"); } 2034 | tDSTAR { $$ = intern_lit("**"); } 2035 | '!' { $$ = intern_lit("!"); } 2036 | '~' { $$ = intern_lit("~"); } 2037 | tUPLUS { $$ = intern_lit("+@"); } 2038 | tUMINUS { $$ = intern_lit("-@"); } 2039 | tAREF { $$ = intern_lit("[]"); } 2040 | tASET { $$ = intern_lit("[]="); } 2041 | '`' { $$ = intern_lit("`"); } 1744 2042 ; 1745 2043 … … 1766 2064 $$ = new_op_asgn(p, $1, $2, $3); 1767 2065 } 1768 | primary_value '[' opt_call_args rbrackettOP_ASGN arg_rhs1769 { 1770 $$ = new_op_asgn(p, new_call(p, $1, intern ("[]",2), $3, '.'), $5, $6);2066 | primary_value '[' opt_call_args ']' tOP_ASGN arg_rhs 2067 { 2068 $$ = new_op_asgn(p, new_call(p, $1, intern_lit("[]"), $3, '.'), $5, $6); 1771 2069 } 1772 2070 | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs … … 1925 2223 $$ = new_if(p, cond($1), $3, $6); 1926 2224 } 2225 | arg '?' arg opt_nl tLABEL_TAG arg 2226 { 2227 $$ = new_if(p, cond($1), $3, $6); 2228 } 1927 2229 | primary 1928 2230 { … … 1939 2241 | args comma assocs trailer 1940 2242 { 1941 $$ = push($1, new_ hash(p, $3));2243 $$ = push($1, new_kw_hash(p, $3)); 1942 2244 } 1943 2245 | assocs trailer 1944 2246 { 1945 $$ = cons(new_ hash(p, $1), 0);2247 $$ = cons(new_kw_hash(p, $1), 0); 1946 2248 NODE_LINENO($$, $1); 1947 2249 } … … 1960 2262 ; 1961 2263 1962 paren_args : '(' opt_call_args rparen2264 paren_args : '(' opt_call_args ')' 1963 2265 { 1964 2266 $$ = $2; … … 1971 2273 1972 2274 opt_call_args : none 1973 | call_args 1974 | args ','2275 | call_args opt_terms 2276 | args comma 1975 2277 { 1976 2278 $$ = cons($1,0); 1977 2279 NODE_LINENO($$, $1); 1978 2280 } 1979 | args comma assocs ','1980 { 1981 $$ = cons(push($1, new_ hash(p, $3)), 0);2281 | args comma assocs comma 2282 { 2283 $$ = cons(push($1, new_kw_hash(p, $3)), 0); 1982 2284 NODE_LINENO($$, $1); 1983 2285 } 1984 | assocs ','1985 { 1986 $$ = cons(list1(new_ hash(p, $1)), 0);2286 | assocs comma 2287 { 2288 $$ = cons(list1(new_kw_hash(p, $1)), 0); 1987 2289 NODE_LINENO($$, $1); 1988 2290 } … … 2002 2304 | assocs opt_block_arg 2003 2305 { 2004 $$ = cons(list1(new_ hash(p, $1)), $2);2306 $$ = cons(list1(new_kw_hash(p, $1)), $2); 2005 2307 NODE_LINENO($$, $1); 2006 2308 } 2007 2309 | args comma assocs opt_block_arg 2008 2310 { 2009 $$ = cons(push($1, new_ hash(p, $3)), $4);2311 $$ = cons(push($1, new_kw_hash(p, $3)), $4); 2010 2312 NODE_LINENO($$, $1); 2011 2313 } … … 2045 2347 2046 2348 comma : ',' 2047 | ',' heredoc_bodies2349 | ',' opt_nl heredoc_bodies 2048 2350 ; 2049 2351 … … 2096 2398 | var_ref 2097 2399 | backref 2400 | tNUMPARAM 2401 { 2402 $$ = new_nvar(p, $1); 2403 } 2098 2404 | tFID 2099 2405 { … … 2248 2554 yyerror(p, "class definition in method body"); 2249 2555 $<nd>$ = local_switch(p); 2556 nvars_block(p); 2250 2557 } 2251 2558 bodystmt … … 2255 2562 SET_LINENO($$, $1); 2256 2563 local_resume(p, $<nd>4); 2564 nvars_unnest(p); 2257 2565 } 2258 2566 | keyword_class … … 2265 2573 { 2266 2574 $<nd>$ = cons(local_switch(p), nint(p->in_single)); 2575 nvars_block(p); 2267 2576 p->in_single = 0; 2268 2577 } … … 2273 2582 SET_LINENO($$, $1); 2274 2583 local_resume(p, $<nd>6->car); 2584 nvars_unnest(p); 2275 2585 p->in_def = $<num>4; 2276 2586 p->in_single = intn($<nd>6->cdr); … … 2282 2592 yyerror(p, "module definition in method body"); 2283 2593 $<nd>$ = local_switch(p); 2594 nvars_block(p); 2284 2595 } 2285 2596 bodystmt … … 2289 2600 SET_LINENO($$, $1); 2290 2601 local_resume(p, $<nd>3); 2602 nvars_unnest(p); 2291 2603 } 2292 2604 | keyword_def fname … … 2298 2610 p->in_def++; 2299 2611 $<nd>$ = local_switch(p); 2612 nvars_block(p); 2300 2613 } 2301 2614 f_arglist … … 2306 2619 SET_LINENO($$, $1); 2307 2620 local_resume(p, $<nd>4); 2621 nvars_unnest(p); 2308 2622 p->in_def--; 2309 2623 p->cmdarg_stack = $<stack>3; … … 2320 2634 p->lstate = EXPR_ENDFN; /* force for args */ 2321 2635 $<nd>$ = local_switch(p); 2636 nvars_block(p); 2322 2637 } 2323 2638 f_arglist … … 2328 2643 SET_LINENO($$, $1); 2329 2644 local_resume(p, $<nd>6); 2645 nvars_unnest(p); 2330 2646 p->in_single--; 2331 2647 p->cmdarg_stack = $<stack>4; … … 2388 2704 ; 2389 2705 2390 f_marg : f_norm_arg 2391 { 2392 $$ = new_arg(p, $1); 2393 } 2394 | tLPAREN f_margs rparen 2395 { 2396 $$ = new_masgn(p, $2, 0); 2397 } 2398 ; 2399 2400 f_marg_list : f_marg 2401 { 2402 $$ = list1($1); 2403 } 2404 | f_marg_list ',' f_marg 2405 { 2406 $$ = push($1, $3); 2407 } 2408 ; 2409 2410 f_margs : f_marg_list 2706 f_margs : f_arg 2411 2707 { 2412 2708 $$ = list3($1,0,0); 2413 2709 } 2414 | f_ marg_list',' tSTAR f_norm_arg2710 | f_arg ',' tSTAR f_norm_arg 2415 2711 { 2416 2712 $$ = list3($1, new_arg(p, $4), 0); 2417 2713 } 2418 | f_ marg_list ',' tSTAR f_norm_arg ',' f_marg_list2714 | f_arg ',' tSTAR f_norm_arg ',' f_arg 2419 2715 { 2420 2716 $$ = list3($1, new_arg(p, $4), $6); 2421 2717 } 2422 | f_marg_list ',' tSTAR 2423 { 2718 | f_arg ',' tSTAR 2719 { 2720 local_add_f(p, 0); 2424 2721 $$ = list3($1, (node*)-1, 0); 2425 2722 } 2426 | f_ marg_list ',' tSTAR ',' f_marg_list2723 | f_arg ',' tSTAR ',' f_arg 2427 2724 { 2428 2725 $$ = list3($1, (node*)-1, $5); … … 2432 2729 $$ = list3(0, new_arg(p, $2), 0); 2433 2730 } 2434 | tSTAR f_norm_arg ',' f_ marg_list2731 | tSTAR f_norm_arg ',' f_arg 2435 2732 { 2436 2733 $$ = list3(0, new_arg(p, $2), $4); … … 2438 2735 | tSTAR 2439 2736 { 2737 local_add_f(p, 0); 2440 2738 $$ = list3(0, (node*)-1, 0); 2441 2739 } 2442 | tSTAR ',' f_marg_list 2443 { 2444 $$ = list3(0, (node*)-1, $3); 2445 } 2446 ; 2447 2448 block_param : f_arg ',' f_block_optarg ',' f_rest_arg opt_f_block_arg 2740 | tSTAR ',' 2741 { 2742 local_add_f(p, 0); 2743 } 2744 f_arg 2745 { 2746 $$ = list3(0, (node*)-1, $4); 2747 } 2748 ; 2749 2750 block_args_tail : f_block_kwarg ',' f_kwrest opt_f_block_arg 2751 { 2752 $$ = new_args_tail(p, $1, $3, $4); 2753 } 2754 | f_block_kwarg opt_f_block_arg 2755 { 2756 $$ = new_args_tail(p, $1, 0, $2); 2757 } 2758 | f_kwrest opt_f_block_arg 2759 { 2760 $$ = new_args_tail(p, 0, $1, $2); 2761 } 2762 | f_block_arg 2763 { 2764 $$ = new_args_tail(p, 0, 0, $1); 2765 } 2766 ; 2767 2768 opt_block_args_tail : ',' block_args_tail 2769 { 2770 $$ = $2; 2771 } 2772 | /* none */ 2773 { 2774 $$ = new_args_tail(p, 0, 0, 0); 2775 } 2776 ; 2777 2778 block_param : f_arg ',' f_block_optarg ',' f_rest_arg opt_block_args_tail 2449 2779 { 2450 2780 $$ = new_args(p, $1, $3, $5, 0, $6); 2451 2781 } 2452 | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_ f_block_arg2782 | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail 2453 2783 { 2454 2784 $$ = new_args(p, $1, $3, $5, $7, $8); 2455 2785 } 2456 | f_arg ',' f_block_optarg opt_ f_block_arg2786 | f_arg ',' f_block_optarg opt_block_args_tail 2457 2787 { 2458 2788 $$ = new_args(p, $1, $3, 0, 0, $4); 2459 2789 } 2460 | f_arg ',' f_block_optarg ',' f_arg opt_ f_block_arg2790 | f_arg ',' f_block_optarg ',' f_arg opt_block_args_tail 2461 2791 { 2462 2792 $$ = new_args(p, $1, $3, 0, $5, $6); 2463 2793 } 2464 | f_arg ',' f_rest_arg opt_ f_block_arg2794 | f_arg ',' f_rest_arg opt_block_args_tail 2465 2795 { 2466 2796 $$ = new_args(p, $1, 0, $3, 0, $4); 2467 2797 } 2468 | f_arg ',' 2469 { 2470 $$ = new_args(p, $1, 0, 0, 0, 0);2471 } 2472 | f_arg ',' f_rest_arg ',' f_arg opt_ f_block_arg2798 | f_arg ',' opt_block_args_tail 2799 { 2800 $$ = new_args(p, $1, 0, 0, 0, $3); 2801 } 2802 | f_arg ',' f_rest_arg ',' f_arg opt_block_args_tail 2473 2803 { 2474 2804 $$ = new_args(p, $1, 0, $3, $5, $6); 2475 2805 } 2476 | f_arg opt_ f_block_arg2806 | f_arg opt_block_args_tail 2477 2807 { 2478 2808 $$ = new_args(p, $1, 0, 0, 0, $2); 2479 2809 } 2480 | f_block_optarg ',' f_rest_arg opt_ f_block_arg2810 | f_block_optarg ',' f_rest_arg opt_block_args_tail 2481 2811 { 2482 2812 $$ = new_args(p, 0, $1, $3, 0, $4); 2483 2813 } 2484 | f_block_optarg ',' f_rest_arg ',' f_arg opt_ f_block_arg2814 | f_block_optarg ',' f_rest_arg ',' f_arg opt_block_args_tail 2485 2815 { 2486 2816 $$ = new_args(p, 0, $1, $3, $5, $6); 2487 2817 } 2488 | f_block_optarg opt_ f_block_arg2818 | f_block_optarg opt_block_args_tail 2489 2819 { 2490 2820 $$ = new_args(p, 0, $1, 0, 0, $2); 2491 2821 } 2492 | f_block_optarg ',' f_arg opt_ f_block_arg2822 | f_block_optarg ',' f_arg opt_block_args_tail 2493 2823 { 2494 2824 $$ = new_args(p, 0, $1, 0, $3, $4); 2495 2825 } 2496 | f_rest_arg opt_ f_block_arg2826 | f_rest_arg opt_block_args_tail 2497 2827 { 2498 2828 $$ = new_args(p, 0, 0, $1, 0, $2); 2499 2829 } 2500 | f_rest_arg ',' f_arg opt_ f_block_arg2830 | f_rest_arg ',' f_arg opt_block_args_tail 2501 2831 { 2502 2832 $$ = new_args(p, 0, 0, $1, $3, $4); 2503 2833 } 2504 | f_block_arg2834 | block_args_tail 2505 2835 { 2506 2836 $$ = new_args(p, 0, 0, 0, 0, $1); … … 2509 2839 2510 2840 opt_block_param : none 2841 { 2842 local_add_blk(p, 0); 2843 $$ = 0; 2844 } 2511 2845 | block_param_def 2512 2846 { 2513 2847 p->cmd_start = TRUE; 2514 2848 $$ = $1; … … 2516 2850 ; 2517 2851 2518 block_param_def : '|' opt_bv_decl '|'2852 block_param_def : '|' {local_add_blk(p, 0);} opt_bv_decl '|' 2519 2853 { 2520 2854 $$ = 0; … … 2522 2856 | tOROP 2523 2857 { 2858 local_add_blk(p, 0); 2524 2859 $$ = 0; 2525 2860 } … … 2567 2902 $$ = $2; 2568 2903 } 2569 | keyword_do_LAMBDA compstmt keyword_end2904 | keyword_do_LAMBDA bodystmt keyword_end 2570 2905 { 2571 2906 $$ = $2; … … 2576 2911 { 2577 2912 local_nest(p); 2913 nvars_nest(p); 2578 2914 } 2579 2915 opt_block_param 2580 compstmt2916 bodystmt 2581 2917 keyword_end 2582 2918 { 2583 2919 $$ = new_block(p,$3,$4); 2584 2920 local_unnest(p); 2921 nvars_unnest(p); 2585 2922 } 2586 2923 ; … … 2630 2967 | primary_value call_op paren_args 2631 2968 { 2632 $$ = new_call(p, $1, intern ("call",4), $3, $2);2969 $$ = new_call(p, $1, intern_lit("call"), $3, $2); 2633 2970 } 2634 2971 | primary_value tCOLON2 paren_args 2635 2972 { 2636 $$ = new_call(p, $1, intern ("call",4), $3, tCOLON2);2973 $$ = new_call(p, $1, intern_lit("call"), $3, tCOLON2); 2637 2974 } 2638 2975 | keyword_super paren_args … … 2644 2981 $$ = new_zsuper(p); 2645 2982 } 2646 | primary_value '[' opt_call_args rbracket2647 { 2648 $$ = new_call(p, $1, intern ("[]",2), $3, '.');2983 | primary_value '[' opt_call_args ']' 2984 { 2985 $$ = new_call(p, $1, intern_lit("[]"), $3, '.'); 2649 2986 } 2650 2987 ; … … 2653 2990 { 2654 2991 local_nest(p); 2992 nvars_nest(p); 2655 2993 $<num>$ = p->lineno; 2656 2994 } … … 2661 2999 SET_LINENO($$, $<num>2); 2662 3000 local_unnest(p); 3001 nvars_unnest(p); 2663 3002 } 2664 3003 | keyword_do 2665 3004 { 2666 3005 local_nest(p); 3006 nvars_nest(p); 2667 3007 $<num>$ = p->lineno; 2668 3008 } 2669 3009 opt_block_param 2670 compstmt keyword_end3010 bodystmt keyword_end 2671 3011 { 2672 3012 $$ = new_block(p,$3,$4); 2673 3013 SET_LINENO($$, $<num>2); 2674 3014 local_unnest(p); 3015 nvars_unnest(p); 2675 3016 } 2676 3017 ; … … 2734 3075 ; 2735 3076 2736 string : tCHAR 3077 string : string_fragment 3078 | string string_fragment 3079 { 3080 $$ = concat_string(p, $1, $2); 3081 } 3082 ; 3083 3084 string_fragment : tCHAR 2737 3085 | tSTRING 2738 3086 | tSTRING_BEG tSTRING … … 2854 3202 symbol : basic_symbol 2855 3203 { 3204 p->lstate = EXPR_ENDARG; 2856 3205 $$ = new_sym(p, $1); 2857 3206 } 2858 3207 | tSYMBEG tSTRING_BEG string_rep tSTRING 2859 3208 { 2860 p->lstate = EXPR_END ;2861 $$ = new_dsym(p, push($3, $4));3209 p->lstate = EXPR_ENDARG; 3210 $$ = new_dsym(p, new_dstr(p, push($3, $4))); 2862 3211 } 2863 3212 ; … … 2865 3214 basic_symbol : tSYMBEG sym 2866 3215 { 2867 p->lstate = EXPR_END;2868 3216 $$ = $2; 2869 3217 } … … 2932 3280 assignable(p, $1); 2933 3281 } 3282 | tNUMPARAM 3283 { 3284 yyerror(p, "can't assign to numbered parameter"); 3285 } 2934 3286 ; 2935 3287 … … 2956 3308 | keyword__FILE__ 2957 3309 { 2958 const char *fn = p->filename;3310 const char *fn = mrb_sym_name_len(p->mrb, p->filename_sym, NULL); 2959 3311 if (!fn) { 2960 3312 fn = "(null)"; … … 2966 3318 char buf[16]; 2967 3319 2968 snprintf(buf, sizeof(buf), "%d", p->lineno); 2969 $$ = new_int(p, buf, 10); 3320 dump_int(p->lineno, buf); 3321 $$ = new_int(p, buf, 10, 0); 3322 } 3323 | keyword__ENCODING__ 3324 { 3325 #ifdef MRB_UTF8_STRING 3326 const char *enc = "UTF-8"; 3327 #else 3328 const char *enc = "ASCII-8BIT"; 3329 #endif 3330 $$ = new_str(p, enc, strlen(enc)); 2970 3331 } 2971 3332 ; … … 3007 3368 ; 3008 3369 3009 f_args : f_arg ',' f_optarg ',' f_rest_arg opt_f_block_arg 3370 f_label : tIDENTIFIER tLABEL_TAG 3371 { 3372 local_nest(p); 3373 } 3374 ; 3375 3376 f_kw : f_label arg 3377 { 3378 void_expr_error(p, $2); 3379 $$ = new_kw_arg(p, $1, cons($2, locals_node(p))); 3380 local_unnest(p); 3381 } 3382 | f_label 3383 { 3384 $$ = new_kw_arg(p, $1, 0); 3385 local_unnest(p); 3386 } 3387 ; 3388 3389 f_block_kw : f_label primary_value 3390 { 3391 $$ = new_kw_arg(p, $1, cons($2, locals_node(p))); 3392 local_unnest(p); 3393 } 3394 | f_label 3395 { 3396 $$ = new_kw_arg(p, $1, 0); 3397 local_unnest(p); 3398 } 3399 ; 3400 3401 f_block_kwarg : f_block_kw 3402 { 3403 $$ = list1($1); 3404 } 3405 | f_block_kwarg ',' f_block_kw 3406 { 3407 $$ = push($1, $3); 3408 } 3409 ; 3410 3411 f_kwarg : f_kw 3412 { 3413 $$ = list1($1); 3414 } 3415 | f_kwarg ',' f_kw 3416 { 3417 $$ = push($1, $3); 3418 } 3419 ; 3420 3421 kwrest_mark : tPOW 3422 | tDSTAR 3423 ; 3424 3425 f_kwrest : kwrest_mark tIDENTIFIER 3426 { 3427 $$ = cons((node*)NODE_KW_REST_ARGS, nsym($2)); 3428 } 3429 | kwrest_mark 3430 { 3431 $$ = cons((node*)NODE_KW_REST_ARGS, 0); 3432 } 3433 ; 3434 3435 args_tail : f_kwarg ',' f_kwrest opt_f_block_arg 3436 { 3437 $$ = new_args_tail(p, $1, $3, $4); 3438 } 3439 | f_kwarg opt_f_block_arg 3440 { 3441 $$ = new_args_tail(p, $1, 0, $2); 3442 } 3443 | f_kwrest opt_f_block_arg 3444 { 3445 $$ = new_args_tail(p, 0, $1, $2); 3446 } 3447 | f_block_arg 3448 { 3449 $$ = new_args_tail(p, 0, 0, $1); 3450 } 3451 ; 3452 3453 opt_args_tail : ',' args_tail 3454 { 3455 $$ = $2; 3456 } 3457 | /* none */ 3458 { 3459 $$ = new_args_tail(p, 0, 0, 0); 3460 } 3461 ; 3462 3463 f_args : f_arg ',' f_optarg ',' f_rest_arg opt_args_tail 3010 3464 { 3011 3465 $$ = new_args(p, $1, $3, $5, 0, $6); 3012 3466 } 3013 | f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_ f_block_arg3467 | f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_args_tail 3014 3468 { 3015 3469 $$ = new_args(p, $1, $3, $5, $7, $8); 3016 3470 } 3017 | f_arg ',' f_optarg opt_ f_block_arg3471 | f_arg ',' f_optarg opt_args_tail 3018 3472 { 3019 3473 $$ = new_args(p, $1, $3, 0, 0, $4); 3020 3474 } 3021 | f_arg ',' f_optarg ',' f_arg opt_ f_block_arg3475 | f_arg ',' f_optarg ',' f_arg opt_args_tail 3022 3476 { 3023 3477 $$ = new_args(p, $1, $3, 0, $5, $6); 3024 3478 } 3025 | f_arg ',' f_rest_arg opt_ f_block_arg3479 | f_arg ',' f_rest_arg opt_args_tail 3026 3480 { 3027 3481 $$ = new_args(p, $1, 0, $3, 0, $4); 3028 3482 } 3029 | f_arg ',' f_rest_arg ',' f_arg opt_ f_block_arg3483 | f_arg ',' f_rest_arg ',' f_arg opt_args_tail 3030 3484 { 3031 3485 $$ = new_args(p, $1, 0, $3, $5, $6); 3032 3486 } 3033 | f_arg opt_ f_block_arg3487 | f_arg opt_args_tail 3034 3488 { 3035 3489 $$ = new_args(p, $1, 0, 0, 0, $2); 3036 3490 } 3037 | f_optarg ',' f_rest_arg opt_ f_block_arg3491 | f_optarg ',' f_rest_arg opt_args_tail 3038 3492 { 3039 3493 $$ = new_args(p, 0, $1, $3, 0, $4); 3040 3494 } 3041 | f_optarg ',' f_rest_arg ',' f_arg opt_ f_block_arg3495 | f_optarg ',' f_rest_arg ',' f_arg opt_args_tail 3042 3496 { 3043 3497 $$ = new_args(p, 0, $1, $3, $5, $6); 3044 3498 } 3045 | f_optarg opt_ f_block_arg3499 | f_optarg opt_args_tail 3046 3500 { 3047 3501 $$ = new_args(p, 0, $1, 0, 0, $2); 3048 3502 } 3049 | f_optarg ',' f_arg opt_ f_block_arg3503 | f_optarg ',' f_arg opt_args_tail 3050 3504 { 3051 3505 $$ = new_args(p, 0, $1, 0, $3, $4); 3052 3506 } 3053 | f_rest_arg opt_ f_block_arg3507 | f_rest_arg opt_args_tail 3054 3508 { 3055 3509 $$ = new_args(p, 0, 0, $1, 0, $2); 3056 3510 } 3057 | f_rest_arg ',' f_arg opt_ f_block_arg3511 | f_rest_arg ',' f_arg opt_args_tail 3058 3512 { 3059 3513 $$ = new_args(p, 0, 0, $1, $3, $4); 3060 3514 } 3061 | f_block_arg3515 | args_tail 3062 3516 { 3063 3517 $$ = new_args(p, 0, 0, 0, 0, $1); … … 3065 3519 | /* none */ 3066 3520 { 3067 local_add_f(p, 0);3521 local_add_f(p, mrb_intern_lit(p->mrb, "&")); 3068 3522 $$ = new_args(p, 0, 0, 0, 0, 0); 3069 3523 } … … 3090 3544 $$ = 0; 3091 3545 } 3546 | tNUMPARAM 3547 { 3548 yyerror(p, "formal argument cannot be a numbered parameter"); 3549 $$ = 0; 3550 } 3092 3551 ; 3093 3552 … … 3107 3566 $$ = new_arg(p, $1); 3108 3567 } 3109 | tLPAREN f_margs rparen 3110 { 3111 $$ = new_masgn(p, $2, 0); 3568 | tLPAREN 3569 { 3570 $<nd>$ = local_switch(p); 3571 } 3572 f_margs rparen 3573 { 3574 $$ = new_masgn_param(p, $3, p->locals->car); 3575 local_resume(p, $<nd>2); 3576 local_add_f(p, 0); 3112 3577 } 3113 3578 ; … … 3126 3591 { 3127 3592 local_add_f(p, $1); 3593 local_nest(p); 3128 3594 $$ = $1; 3129 3595 } … … 3133 3599 { 3134 3600 void_expr_error(p, $2); 3135 $$ = cons(nsym($1), $2); 3601 $$ = cons(nsym($1), cons($2, locals_node(p))); 3602 local_unnest(p); 3136 3603 } 3137 3604 ; … … 3140 3607 { 3141 3608 void_expr_error(p, $2); 3142 $$ = cons(nsym($1), $2); 3609 $$ = cons(nsym($1), cons($2, locals_node(p))); 3610 local_unnest(p); 3143 3611 } 3144 3612 ; … … 3175 3643 | restarg_mark 3176 3644 { 3177 local_add_f(p, 0);3645 local_add_f(p, mrb_intern_lit(p->mrb, "*")); 3178 3646 $$ = -1; 3179 3647 } … … 3186 3654 f_block_arg : blkarg_mark tIDENTIFIER 3187 3655 { 3188 local_add_f(p, $2);3189 3656 $$ = $2; 3190 3657 } … … 3197 3664 | none 3198 3665 { 3199 local_add_f(p, 0);3200 3666 $$ = 0; 3201 3667 } … … 3244 3710 NODE_LINENO($$, $1); 3245 3711 } 3246 | assocs ','assoc3712 | assocs comma assoc 3247 3713 { 3248 3714 $$ = push($1, $3); 3249 3715 } 3716 ; 3717 3718 label_tag : tLABEL_TAG 3719 | tLABEL_TAG heredoc_bodies 3250 3720 ; 3251 3721 … … 3256 3726 $$ = cons($1, $3); 3257 3727 } 3258 | tLABEL arg 3728 | tIDENTIFIER label_tag arg 3729 { 3730 void_expr_error(p, $3); 3731 $$ = cons(new_sym(p, $1), $3); 3732 } 3733 | string_fragment label_tag arg 3734 { 3735 void_expr_error(p, $3); 3736 if ($1->car == (node*)NODE_DSTR) { 3737 $$ = cons(new_dsym(p, $1), $3); 3738 } 3739 else { 3740 $$ = cons(new_sym(p, new_strsym(p, $1)), $3); 3741 } 3742 } 3743 | tDSTAR arg 3259 3744 { 3260 3745 void_expr_error(p, $2); 3261 $$ = cons(new_sym(p, $1), $2); 3262 } 3263 | tLABEL_END arg 3264 { 3265 void_expr_error(p, $2); 3266 $$ = cons(new_sym(p, new_strsym(p, $1)), $2); 3267 } 3268 | tSTRING_BEG tLABEL_END arg 3269 { 3270 void_expr_error(p, $3); 3271 $$ = cons(new_sym(p, new_strsym(p, $2)), $3); 3272 } 3273 | tSTRING_BEG string_rep tLABEL_END arg 3274 { 3275 void_expr_error(p, $4); 3276 $$ = cons(new_dsym(p, push($2, $3)), $4); 3746 $$ = cons(cons((node*)NODE_KW_REST_ARGS, 0), $2); 3277 3747 } 3278 3748 ; … … 3323 3793 ; 3324 3794 3325 rparen : opt_nl ')' 3326 ; 3327 3328 rbracket : opt_nl ']' 3795 rparen : opt_terms ')' 3329 3796 ; 3330 3797 3331 3798 trailer : /* none */ 3332 | nl3799 | terms 3333 3800 | comma 3334 3801 ; … … 3362 3829 { 3363 3830 char* c; 3364 int n;3831 size_t n; 3365 3832 3366 3833 if (! p->capture_errors) { 3367 3834 #ifndef MRB_DISABLE_STDIO 3368 if (p->filename) { 3369 fprintf(stderr, "%s:%d:%d: %s\n", p->filename, p->lineno, p->column, s); 3835 if (p->filename_sym) { 3836 const char *filename = mrb_sym_name_len(p->mrb, p->filename_sym, NULL); 3837 fprintf(stderr, "%s:%d:%d: %s\n", filename, p->lineno, p->column, s); 3370 3838 } 3371 3839 else { … … 3386 3854 3387 3855 static void 3388 yyerror_ i(parser_state *p, const char *fmt, int i)3856 yyerror_c(parser_state *p, const char *msg, char c) 3389 3857 { 3390 3858 char buf[256]; 3391 3859 3392 snprintf(buf, sizeof(buf), fmt, i); 3860 strncpy(buf, msg, sizeof(buf) - 2); 3861 buf[sizeof(buf) - 2] = '\0'; 3862 strncat(buf, &c, 1); 3393 3863 yyerror(p, buf); 3394 3864 } … … 3398 3868 { 3399 3869 char* c; 3400 int n;3870 size_t n; 3401 3871 3402 3872 if (! p->capture_errors) { 3403 3873 #ifndef MRB_DISABLE_STDIO 3404 if (p->filename) { 3405 fprintf(stderr, "%s:%d:%d: %s\n", p->filename, p->lineno, p->column, s); 3874 if (p->filename_sym) { 3875 const char *filename = mrb_sym_name_len(p->mrb, p->filename_sym, NULL); 3876 fprintf(stderr, "%s:%d:%d: warning: %s\n", filename, p->lineno, p->column, s); 3406 3877 } 3407 3878 else { 3408 fprintf(stderr, "line %d:%d: %s\n", p->lineno, p->column, s);3879 fprintf(stderr, "line %d:%d: warning: %s\n", p->lineno, p->column, s); 3409 3880 } 3410 3881 #endif … … 3428 3899 3429 3900 static void 3430 yywarning_s(parser_state *p, const char * fmt, const char *s)3901 yywarning_s(parser_state *p, const char *msg, const char *s) 3431 3902 { 3432 3903 char buf[256]; 3433 3904 3434 snprintf(buf, sizeof(buf), fmt, s); 3905 strncpy(buf, msg, sizeof(buf) - 1); 3906 buf[sizeof(buf) - 1] = '\0'; 3907 strncat(buf, ": ", sizeof(buf) - strlen(buf) - 1); 3908 strncat(buf, s, sizeof(buf) - strlen(buf) - 1); 3435 3909 yywarning(p, buf); 3436 3910 } … … 3441 3915 int c; 3442 3916 3443 c = (int)(intptr_t)n->car;3917 c = intn(n->car); 3444 3918 3445 3919 if (c == NODE_NTH_REF) { 3446 yyerror_ i(p, "can't set variable $%" MRB_PRId, (mrb_int)(intptr_t)n->cdr);3920 yyerror_c(p, "can't set variable $", (char)intn(n->cdr)+'0'); 3447 3921 } 3448 3922 else if (c == NODE_BACK_REF) { 3449 yyerror_ i(p, "can't set variable $%c", (int)(intptr_t)n->cdr);3923 yyerror_c(p, "can't set variable $", (char)intn(n->cdr)); 3450 3924 } 3451 3925 else { 3452 mrb_bug(p->mrb, "Internal error in backref_error() : n=>car == % S", mrb_fixnum_value(c));3926 mrb_bug(p->mrb, "Internal error in backref_error() : n=>car == %d", c); 3453 3927 } 3454 3928 } … … 3460 3934 3461 3935 if (n == NULL) return; 3462 c = (int)(intptr_t)n->car;3936 c = intn(n->car); 3463 3937 switch (c) { 3464 3938 case NODE_BREAK: … … 3471 3945 case NODE_AND: 3472 3946 case NODE_OR: 3473 void_expr_error(p, n->cdr->car); 3474 void_expr_error(p, n->cdr->cdr); 3947 if (n->cdr) { 3948 void_expr_error(p, n->cdr->car); 3949 void_expr_error(p, n->cdr->cdr); 3950 } 3475 3951 break; 3476 3952 case NODE_BEGIN: … … 3492 3968 3493 3969 static inline int 3970 nextc0(parser_state *p) 3971 { 3972 int c; 3973 #ifndef MRB_DISABLE_STDIO 3974 if (p->f) { 3975 if (feof(p->f)) return -1; 3976 c = fgetc(p->f); 3977 if (c == EOF) return -1; 3978 } 3979 else 3980 #endif 3981 if (!p->s || p->s >= p->send) { 3982 return -1; 3983 } 3984 else { 3985 c = (unsigned char)*p->s++; 3986 } 3987 return c; 3988 } 3989 3990 static inline int 3494 3991 nextc(parser_state *p) 3495 3992 { … … 3499 3996 node *tmp; 3500 3997 3501 c = (int)(intptr_t)p->pb->car;3998 c = intn(p->pb->car); 3502 3999 tmp = p->pb; 3503 4000 p->pb = p->pb->cdr; … … 3505 4002 } 3506 4003 else { 3507 #ifndef MRB_DISABLE_STDIO 3508 if (p->f) { 3509 if (feof(p->f)) goto eof; 3510 c = fgetc(p->f); 3511 if (c == EOF) goto eof; 3512 } 3513 else 3514 #endif 3515 if (!p->s || p->s >= p->send) { 3516 goto eof; 3517 } 3518 else { 3519 c = (unsigned char)*p->s++; 3520 } 4004 c = nextc0(p); 4005 if (c < 0) goto eof; 3521 4006 } 3522 4007 if (c >= 0) { … … 3524 4009 } 3525 4010 if (c == '\r') { 3526 c = nextc(p); 3527 if (c != '\n') { 3528 pushback(p, c); 3529 return '\r'; 3530 } 3531 return c; 4011 const int lf = nextc0(p); 4012 if (lf == '\n') { 4013 return '\n'; 4014 } 4015 if (lf > 0) pushback(p, lf); 3532 4016 } 3533 4017 return c; … … 3548 4032 p->column--; 3549 4033 } 3550 p->pb = cons( (node*)(intptr_t)c, p->pb);4034 p->pb = cons(nint(c), p->pb); 3551 4035 } 3552 4036 … … 3573 4057 if (c0 == -1) return c0; /* do not skip partial EOF */ 3574 4058 if (c0 >= 0) --p->column; 3575 list = push(list, (node*)(intptr_t)c0);4059 list = push(list, nint(c0)); 3576 4060 } while(n--); 3577 4061 if (p->pb) { … … 3594 4078 peeks(parser_state *p, const char *s) 3595 4079 { 3596 int len = strlen(s);4080 size_t len = strlen(s); 3597 4081 3598 4082 #ifndef MRB_DISABLE_STDIO … … 3630 4114 s++; 3631 4115 if (peeks(p, s)) { 3632 int len = strlen(s);4116 size_t len = strlen(s); 3633 4117 3634 4118 while (len--) { … … 3752 4236 #define IS_LABEL_SUFFIX(n) (peek_n(p, ':',(n)) && !peek_n(p, ':', (n)+1)) 3753 4237 3754 static int 4238 static int32_t 3755 4239 scan_oct(const int *start, int len, int *retlen) 3756 4240 { 3757 4241 const int *s = start; 3758 int retval = 0;4242 int32_t retval = 0; 3759 4243 3760 4244 /* mrb_assert(len <= 3) */ … … 3763 4247 retval |= *s++ - '0'; 3764 4248 } 3765 *retlen = s - start;4249 *retlen = (int)(s - start); 3766 4250 3767 4251 return retval; … … 3769 4253 3770 4254 static int32_t 3771 scan_hex( const int *start, int len, int *retlen)4255 scan_hex(parser_state *p, const int *start, int len, int *retlen) 3772 4256 { 3773 4257 static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF"; 3774 4258 const int *s = start; 3775 int32_t retval = 0;4259 uint32_t retval = 0; 3776 4260 char *tmp; 3777 4261 … … 3782 4266 s++; 3783 4267 } 3784 *retlen = s - start;3785 3786 return retval;4268 *retlen = (int)(s - start); 4269 4270 return (int32_t)retval; 3787 4271 } 3788 4272 … … 3790 4274 read_escape_unicode(parser_state *p, int limit) 3791 4275 { 3792 int32_t c;3793 4276 int buf[9]; 3794 4277 int i; 4278 int32_t hex; 3795 4279 3796 4280 /* Look for opening brace */ 3797 4281 i = 0; 3798 4282 buf[0] = nextc(p); 3799 if (buf[0] < 0) goto eof; 4283 if (buf[0] < 0) { 4284 eof: 4285 yyerror(p, "invalid escape character syntax"); 4286 return -1; 4287 } 3800 4288 if (ISXDIGIT(buf[0])) { 3801 4289 /* \uxxxx form */ … … 3812 4300 pushback(p, buf[0]); 3813 4301 } 3814 c = scan_hex(buf, i, &i); 3815 if (i == 0) { 3816 eof: 3817 yyerror(p, "Invalid escape character syntax"); 4302 hex = scan_hex(p, buf, i, &i); 4303 if (i == 0 || hex > 0x10FFFF || (hex & 0xFFFFF800) == 0xD800) { 4304 yyerror(p, "invalid Unicode code point"); 3818 4305 return -1; 3819 4306 } 3820 if (c < 0 || c > 0x10FFFF || (c & 0xFFFFF800) == 0xD800) { 3821 yyerror(p, "Invalid Unicode code point"); 3822 return -1; 3823 } 3824 return c; 4307 return hex; 3825 4308 } 3826 4309 … … 3888 4371 } 3889 4372 } 3890 c = scan_hex(buf, i, &i);3891 4373 if (i == 0) { 3892 yyerror(p, " Invalid escape character syntax");3893 return 0;3894 } 3895 }3896 return c;4374 yyerror(p, "invalid hex escape"); 4375 return -1; 4376 } 4377 return scan_hex(p, buf, i, &i); 4378 } 3897 4379 3898 4380 case 'u': /* Unicode */ … … 3961 4443 int c; 3962 4444 string_type type = (string_type)(intptr_t)p->lex_strterm->car; 3963 int nest_level = (intptr_t)p->lex_strterm->cdr->car;3964 int beg = (intptr_t)p->lex_strterm->cdr->cdr->car;3965 int end = (intptr_t)p->lex_strterm->cdr->cdr->cdr;4445 int nest_level = intn(p->lex_strterm->cdr->car); 4446 int beg = intn(p->lex_strterm->cdr->cdr->car); 4447 int end = intn(p->lex_strterm->cdr->cdr->cdr); 3966 4448 parser_heredoc_info *hinf = (type & STR_FUNC_HEREDOC) ? parsing_heredoc_inf(p) : NULL; 3967 int cmd_state = p->cmd_start;3968 4449 3969 4450 if (beg == 0) beg = -3; /* should never happen */ … … 3990 4471 } 3991 4472 if ((len-1 == hinf->term_len) && (strncmp(s, hinf->term, len-1) == 0)) { 3992 if (c < 0) { 3993 p->parsing_heredoc = NULL; 3994 } 3995 else { 3996 return tHEREDOC_END; 3997 } 4473 return tHEREDOC_END; 3998 4474 } 3999 4475 } 4000 4476 if (c < 0) { 4001 4477 char buf[256]; 4002 snprintf(buf, sizeof(buf), "can't find heredoc delimiter \"%s\" anywhere before EOF", hinf->term); 4003 yyerror(p, buf); 4478 const char s1[] = "can't find heredoc delimiter \""; 4479 const char s2[] = "\" anywhere before EOF"; 4480 4481 if (sizeof(s1)+sizeof(s2)+strlen(hinf->term)+1 >= sizeof(buf)) { 4482 yyerror(p, "can't find heredoc delimiter anywhere before EOF"); 4483 } else { 4484 strcpy(buf, s1); 4485 strcat(buf, hinf->term); 4486 strcat(buf, s2); 4487 yyerror(p, buf); 4488 } 4004 4489 return 0; 4005 4490 } … … 4013 4498 else if (c == beg) { 4014 4499 nest_level++; 4015 p->lex_strterm->cdr->car = (node*)(intptr_t)nest_level;4500 p->lex_strterm->cdr->car = nint(nest_level); 4016 4501 } 4017 4502 else if (c == end) { 4018 4503 nest_level--; 4019 p->lex_strterm->cdr->car = (node*)(intptr_t)nest_level;4504 p->lex_strterm->cdr->car = nint(nest_level); 4020 4505 } 4021 4506 else if (c == '\\') { … … 4119 4604 4120 4605 tokfix(p); 4121 p->lstate = EXPR_END ;4606 p->lstate = EXPR_ENDARG; 4122 4607 end_strterm(p); 4123 4608 … … 4145 4630 case 'u': f |= 16; break; 4146 4631 case 'n': f |= 32; break; 4632 case 'o': break; 4147 4633 default: tokadd(p, re_opt); break; 4148 4634 } … … 4151 4637 if (toklen(p)) { 4152 4638 char msg[128]; 4639 4640 strcpy(msg, "unknown regexp option"); 4153 4641 tokfix(p); 4154 snprintf(msg, sizeof(msg), "unknown regexp option%s - %s", 4155 toklen(p) > 1 ? "s" : "", tok(p)); 4642 if (toklen(p) > 1) { 4643 strcat(msg, "s"); 4644 } 4645 strcat(msg, " - "); 4646 strncat(msg, tok(p), sizeof(msg) - strlen(msg) - 1); 4156 4647 yyerror(p, msg); 4157 4648 } … … 4180 4671 } 4181 4672 pylval.nd = new_str(p, tok(p), toklen(p)); 4182 if (IS_LABEL_POSSIBLE()) {4183 if (IS_LABEL_SUFFIX(0)) {4184 p->lstate = EXPR_BEG;4185 nextc(p);4186 return tLABEL_END;4187 }4188 }4189 4673 4190 4674 return tSTRING; 4191 4675 } 4192 4676 4677 static int 4678 number_literal_suffix(parser_state *p) 4679 { 4680 int c, result = 0; 4681 node *list = 0; 4682 int column = p->column; 4683 int mask = NUM_SUFFIX_R|NUM_SUFFIX_I; 4684 4685 while ((c = nextc(p)) != -1) { 4686 list = push(list, (node*)(intptr_t)c); 4687 4688 if ((mask & NUM_SUFFIX_I) && c == 'i') { 4689 result |= (mask & NUM_SUFFIX_I); 4690 mask &= ~NUM_SUFFIX_I; 4691 /* r after i, rational of complex is disallowed */ 4692 mask &= ~NUM_SUFFIX_R; 4693 continue; 4694 } 4695 if ((mask & NUM_SUFFIX_R) && c == 'r') { 4696 result |= (mask & NUM_SUFFIX_R); 4697 mask &= ~NUM_SUFFIX_R; 4698 continue; 4699 } 4700 if (!ISASCII(c) || ISALPHA(c) || c == '_') { 4701 p->column = column; 4702 if (p->pb) { 4703 p->pb = append((node*)list, p->pb); 4704 } 4705 else { 4706 p->pb = list; 4707 } 4708 return 0; 4709 } 4710 pushback(p, c); 4711 break; 4712 } 4713 return result; 4714 } 4193 4715 4194 4716 static int … … 4311 4833 case -2: /* end of a file */ 4312 4834 case '\n': 4313 4835 maybe_heredoc: 4314 4836 heredoc_treat_nextline(p); 4315 switch (p->lstate) {4316 case EXPR_BEG:4317 case EXPR_FNAME:4318 case EXPR_DOT:4319 case EXPR_CLASS:4320 case EXPR_VALUE:4321 p->lineno++;4322 4837 p->column = 0; 4838 switch (p->lstate) { 4839 case EXPR_BEG: 4840 case EXPR_FNAME: 4841 case EXPR_DOT: 4842 case EXPR_CLASS: 4843 case EXPR_VALUE: 4844 p->lineno++; 4845 if (p->parsing_heredoc != NULL) { 4846 if (p->lex_strterm) { 4847 return parse_string(p); 4848 } 4849 } 4850 goto retry; 4851 default: 4852 break; 4853 } 4323 4854 if (p->parsing_heredoc != NULL) { 4324 if (p->lex_strterm) { 4325 return parse_string(p); 4326 } 4327 } 4328 goto retry; 4329 default: 4330 break; 4331 } 4332 if (p->parsing_heredoc != NULL) { 4855 return '\n'; 4856 } 4857 while ((c = nextc(p))) { 4858 switch (c) { 4859 case ' ': case '\t': case '\f': case '\r': 4860 case '\13': /* '\v' */ 4861 space_seen = 1; 4862 break; 4863 case '#': /* comment as a whitespace */ 4864 pushback(p, '#'); 4865 p->lineno++; 4866 goto retry; 4867 case '.': 4868 if (!peek(p, '.')) { 4869 pushback(p, '.'); 4870 p->lineno++; 4871 goto retry; 4872 } 4873 pushback(p, c); 4874 goto normal_newline; 4875 case '&': 4876 if (peek(p, '.')) { 4877 pushback(p, '&'); 4878 p->lineno++; 4879 goto retry; 4880 } 4881 pushback(p, c); 4882 goto normal_newline; 4883 case -1: /* EOF */ 4884 case -2: /* end of a file */ 4885 goto normal_newline; 4886 default: 4887 pushback(p, c); 4888 goto normal_newline; 4889 } 4890 } 4891 normal_newline: 4892 p->cmd_start = TRUE; 4893 p->lstate = EXPR_BEG; 4333 4894 return '\n'; 4334 }4335 while ((c = nextc(p))) {4336 switch (c) {4337 case ' ': case '\t': case '\f': case '\r':4338 case '\13': /* '\v' */4339 space_seen = 1;4340 break;4341 case '.':4342 if ((c = nextc(p)) != '.') {4343 pushback(p, c);4344 pushback(p, '.');4345 goto retry;4346 }4347 case -1: /* EOF */4348 case -2: /* end of a file */4349 goto normal_newline;4350 default:4351 pushback(p, c);4352 goto normal_newline;4353 }4354 }4355 normal_newline:4356 p->cmd_start = TRUE;4357 p->lstate = EXPR_BEG;4358 return '\n';4359 4895 4360 4896 case '*': 4361 4897 if ((c = nextc(p)) == '*') { 4362 4898 if ((c = nextc(p)) == '=') { 4363 pylval.id = intern ("**",2);4899 pylval.id = intern_lit("**"); 4364 4900 p->lstate = EXPR_BEG; 4365 4901 return tOP_ASGN; 4366 4902 } 4367 4903 pushback(p, c); 4368 c = tPOW; 4904 if (IS_SPCARG(c)) { 4905 yywarning(p, "'**' interpreted as argument prefix"); 4906 c = tDSTAR; 4907 } 4908 else if (IS_BEG()) { 4909 c = tDSTAR; 4910 } 4911 else { 4912 c = tPOW; /* "**", "argument prefix" */ 4913 } 4369 4914 } 4370 4915 else { 4371 4916 if (c == '=') { 4372 pylval.id = intern_ c('*');4917 pylval.id = intern_lit("*"); 4373 4918 p->lstate = EXPR_BEG; 4374 4919 return tOP_ASGN; … … 4486 5031 if (c == '<') { 4487 5032 if ((c = nextc(p)) == '=') { 4488 pylval.id = intern ("<<",2);5033 pylval.id = intern_lit("<<"); 4489 5034 p->lstate = EXPR_BEG; 4490 5035 return tOP_ASGN; … … 4508 5053 if (c == '>') { 4509 5054 if ((c = nextc(p)) == '=') { 4510 pylval.id = intern (">>",2);5055 pylval.id = intern_lit(">>"); 4511 5056 p->lstate = EXPR_BEG; 4512 5057 return tOP_ASGN; … … 4579 5124 if (c2) { 4580 5125 char buf[256]; 4581 snprintf(buf, sizeof(buf), "invalid character syntax; use ?\\%c", c2); 5126 char cc[] = { (char)c2, '\0' }; 5127 5128 strcpy(buf, "invalid character syntax; use ?\\"); 5129 strncat(buf, cc, 2); 4582 5130 yyerror(p, buf); 4583 5131 } … … 4590 5138 newtok(p); 4591 5139 /* need support UTF-8 if configured */ 4592 if (( isalnum(c) || c == '_')) {5140 if ((ISALNUM(c) || c == '_')) { 4593 5141 int c2 = nextc(p); 4594 5142 pushback(p, c2); 4595 if (( isalnum(c2) || c2 == '_')) {5143 if ((ISALNUM(c2) || c2 == '_')) { 4596 5144 goto ternary; 4597 5145 } … … 4606 5154 tokfix(p); 4607 5155 pylval.nd = new_str(p, tok(p), toklen(p)); 4608 p->lstate = EXPR_END ;5156 p->lstate = EXPR_ENDARG; 4609 5157 return tCHAR; 4610 5158 … … 4613 5161 p->lstate = EXPR_BEG; 4614 5162 if ((c = nextc(p)) == '=') { 4615 pylval.id = intern ("&&",2);5163 pylval.id = intern_lit("&&"); 4616 5164 p->lstate = EXPR_BEG; 4617 5165 return tOP_ASGN; … … 4625 5173 } 4626 5174 else if (c == '=') { 4627 pylval.id = intern_ c('&');5175 pylval.id = intern_lit("&"); 4628 5176 p->lstate = EXPR_BEG; 4629 5177 return tOP_ASGN; … … 4652 5200 p->lstate = EXPR_BEG; 4653 5201 if ((c = nextc(p)) == '=') { 4654 pylval.id = intern ("||",2);5202 pylval.id = intern_lit("||"); 4655 5203 p->lstate = EXPR_BEG; 4656 5204 return tOP_ASGN; … … 4660 5208 } 4661 5209 if (c == '=') { 4662 pylval.id = intern_ c('|');5210 pylval.id = intern_lit("|"); 4663 5211 p->lstate = EXPR_BEG; 4664 5212 return tOP_ASGN; … … 4684 5232 } 4685 5233 if (c == '=') { 4686 pylval.id = intern_ c('+');5234 pylval.id = intern_lit("+"); 4687 5235 p->lstate = EXPR_BEG; 4688 5236 return tOP_ASGN; … … 4712 5260 } 4713 5261 if (c == '=') { 4714 pylval.id = intern_ c('-');5262 pylval.id = intern_lit("-"); 4715 5263 p->lstate = EXPR_BEG; 4716 5264 return tOP_ASGN; … … 4753 5301 { 4754 5302 int is_float, seen_point, seen_e, nondigit; 5303 int suffix = 0; 4755 5304 4756 5305 is_float = seen_point = seen_e = nondigit = 0; 4757 p->lstate = EXPR_END ;5306 p->lstate = EXPR_ENDARG; 4758 5307 newtok(p); 4759 5308 if (c == '-' || c == '+') { … … 4786 5335 } 4787 5336 else if (nondigit) goto trailing_uc; 4788 pylval.nd = new_int(p, tok(p), 16); 5337 suffix = number_literal_suffix(p); 5338 pylval.nd = new_int(p, tok(p), 16, suffix); 4789 5339 return tINTEGER; 4790 5340 } … … 4810 5360 } 4811 5361 else if (nondigit) goto trailing_uc; 4812 pylval.nd = new_int(p, tok(p), 2); 5362 suffix = number_literal_suffix(p); 5363 pylval.nd = new_int(p, tok(p), 2, suffix); 4813 5364 return tINTEGER; 4814 5365 } … … 4834 5385 } 4835 5386 else if (nondigit) goto trailing_uc; 4836 pylval.nd = new_int(p, tok(p), 10); 5387 suffix = number_literal_suffix(p); 5388 pylval.nd = new_int(p, tok(p), 10, suffix); 4837 5389 return tINTEGER; 4838 5390 } … … 4867 5419 tokfix(p); 4868 5420 if (nondigit) goto trailing_uc; 4869 pylval.nd = new_int(p, tok(p), 8); 5421 suffix = number_literal_suffix(p); 5422 pylval.nd = new_int(p, tok(p), 8, suffix); 4870 5423 return tINTEGER; 4871 5424 } … … 4884 5437 else { 4885 5438 pushback(p, c); 4886 pylval.nd = new_int(p, "0", 10); 5439 suffix = number_literal_suffix(p); 5440 pylval.nd = new_int(p, "0", 10, suffix); 4887 5441 return tINTEGER; 4888 5442 } … … 4952 5506 if (nondigit) { 4953 5507 trailing_uc: 4954 yyerror_ i(p, "trailing '%c' in number",nondigit);5508 yyerror_c(p, "trailing non digit in number: ", (char)nondigit); 4955 5509 } 4956 5510 tokfix(p); 4957 5511 if (is_float) { 5512 #ifdef MRB_WITHOUT_FLOAT 5513 yywarning_s(p, "floating point numbers are not supported", tok(p)); 5514 pylval.nd = new_int(p, "0", 10, 0); 5515 return tINTEGER; 5516 #else 4958 5517 double d; 4959 5518 char *endp; … … 4962 5521 d = mrb_float_read(tok(p), &endp); 4963 5522 if (d == 0 && endp == tok(p)) { 4964 yywarning_s(p, "corrupted float value %s", tok(p));5523 yywarning_s(p, "corrupted float value", tok(p)); 4965 5524 } 4966 5525 else if (errno == ERANGE) { 4967 yywarning_s(p, "float %sout of range", tok(p));5526 yywarning_s(p, "float out of range", tok(p)); 4968 5527 errno = 0; 4969 5528 } 4970 pylval.nd = new_float(p, tok(p)); 5529 suffix = number_literal_suffix(p); 5530 pylval.nd = new_float(p, tok(p), suffix); 4971 5531 return tFLOAT; 4972 } 4973 pylval.nd = new_int(p, tok(p), 10); 5532 #endif 5533 } 5534 suffix = number_literal_suffix(p); 5535 pylval.nd = new_int(p, tok(p), 10, suffix); 4974 5536 return tINTEGER; 4975 5537 } … … 4985 5547 p->lstate = EXPR_ENDFN; 4986 5548 else 4987 p->lstate = EXPR_END ARG;5549 p->lstate = EXPR_END; 4988 5550 return c; 4989 5551 … … 4998 5560 return tCOLON2; 4999 5561 } 5000 if ( IS_END() || ISSPACE(c)) {5562 if (!space_seen && IS_END()) { 5001 5563 pushback(p, c); 5002 5564 p->lstate = EXPR_BEG; 5003 return ':'; 5565 return tLABEL_TAG; 5566 } 5567 if (!ISSPACE(c) || IS_BEG()) { 5568 pushback(p, c); 5569 p->lstate = EXPR_FNAME; 5570 return tSYMBEG; 5004 5571 } 5005 5572 pushback(p, c); 5006 p->lstate = EXPR_ FNAME;5007 return tSYMBEG;5573 p->lstate = EXPR_BEG; 5574 return ':'; 5008 5575 5009 5576 case '/': … … 5013 5580 } 5014 5581 if ((c = nextc(p)) == '=') { 5015 pylval.id = intern_ c('/');5582 pylval.id = intern_lit("/"); 5016 5583 p->lstate = EXPR_BEG; 5017 5584 return tOP_ASGN; … … 5032 5599 case '^': 5033 5600 if ((c = nextc(p)) == '=') { 5034 pylval.id = intern_ c('^');5601 pylval.id = intern_lit("^"); 5035 5602 p->lstate = EXPR_BEG; 5036 5603 return tOP_ASGN; … … 5070 5637 } 5071 5638 else if (IS_SPCARG(-1)) { 5639 c = tLPAREN_ARG; 5640 } 5641 else if (p->lstate == EXPR_END && space_seen) { 5072 5642 c = tLPAREN_ARG; 5073 5643 } … … 5147 5717 else { 5148 5718 term = nextc(p); 5149 if ( isalnum(term)) {5719 if (ISALNUM(term)) { 5150 5720 yyerror(p, "unknown type of %string"); 5151 5721 return 0; … … 5206 5776 } 5207 5777 if ((c = nextc(p)) == '=') { 5208 pylval.id = intern_ c('%');5778 pylval.id = intern_lit("%"); 5209 5779 p->lstate = EXPR_BEG; 5210 5780 return tOP_ASGN; … … 5260 5830 tokadd(p, c); 5261 5831 tokfix(p); 5262 pylval.id = intern _cstr(tok(p));5832 pylval.id = intern(tok(p), toklen(p)); 5263 5833 return tGVAR; 5264 5834 … … 5270 5840 gvar: 5271 5841 tokfix(p); 5272 pylval.id = intern _cstr(tok(p));5842 pylval.id = intern(tok(p), toklen(p)); 5273 5843 return tGVAR; 5274 5844 … … 5291 5861 tokadd(p, c); 5292 5862 c = nextc(p); 5293 } while (c >= 0 && isdigit(c));5863 } while (c >= 0 && ISDIGIT(c)); 5294 5864 pushback(p, c); 5295 5865 if (last_state == EXPR_FNAME) goto gvar; … … 5298 5868 unsigned long n = strtoul(tok(p), NULL, 10); 5299 5869 if (n > INT_MAX) { 5300 yyerror _i(p, "capture group index must be <= %d", INT_MAX);5870 yyerror(p, "capture group index must be <= " MRB_STRINGIZE(INT_MAX)); 5301 5871 return 0; 5302 5872 } … … 5333 5903 return 0; 5334 5904 } 5335 else if ( isdigit(c)) {5905 else if (ISDIGIT(c)) { 5336 5906 if (p->tidx == 1) { 5337 yyerror_ i(p, "'@%c' is not allowed as an instance variable name", c);5907 yyerror_c(p, "wrong instance variable name: @", c); 5338 5908 } 5339 5909 else { 5340 yyerror_ i(p, "'@@%c' is not allowed as a class variable name", c);5910 yyerror_c(p, "wrong class variable name: @@", c); 5341 5911 } 5342 5912 return 0; … … 5354 5924 default: 5355 5925 if (!identchar(c)) { 5356 yyerror_i(p, "Invalid char '\\x%02X' in expression", c); 5926 char buf[36]; 5927 const char s[] = "Invalid char in expression: 0x"; 5928 const char hexdigits[] = "0123456789ABCDEF"; 5929 5930 strcpy(buf, s); 5931 buf[sizeof(s)-1] = hexdigits[(c & 0xf0) >> 4]; 5932 buf[sizeof(s)] = hexdigits[(c & 0x0f)]; 5933 buf[sizeof(s)+1] = 0; 5934 yyerror(p, buf); 5357 5935 goto retry; 5358 5936 } … … 5400 5978 break; 5401 5979 5980 case '_': 5981 if (toklen(p) == 2 && ISDIGIT(tok(p)[1]) && p->nvars) { 5982 int n = tok(p)[1] - '0'; 5983 int nvar; 5984 5985 if (n > 0) { 5986 node *nvars = p->nvars->cdr; 5987 5988 while (nvars) { 5989 nvar = intn(nvars->car); 5990 if (nvar == -2) break; /* top of the scope */ 5991 if (nvar > 0) { 5992 yywarning(p, "numbered parameter used in outer block"); 5993 break; 5994 } 5995 nvars->car = nint(-1); 5996 nvars = nvars->cdr; 5997 } 5998 nvar = intn(p->nvars->car); 5999 if (nvar == -1) { 6000 yywarning(p, "numbered parameter used in inner block"); 6001 } 6002 if (nvar >= -1) { 6003 pylval.num = n; 6004 p->lstate = EXPR_END; 6005 return tNUMPARAM; 6006 } 6007 else { 6008 yywarning(p, "identifier for numbered parameter; consider another name"); 6009 } 6010 } 6011 } 6012 /* fall through */ 5402 6013 default: 5403 6014 if (toklast(p) == '!' || toklast(p) == '?') { … … 5406 6017 else { 5407 6018 if (p->lstate == EXPR_FNAME) { 6019 if ((c = nextc(p)) == '=' && !peek(p, '~') && !peek(p, '>') && 6020 (!peek(p, '=') || (peek_n(p, '>', 1)))) { 6021 result = tIDENTIFIER; 6022 tokadd(p, c); 6023 tokfix(p); 6024 } 6025 else { 6026 pushback(p, c); 6027 } 5408 6028 if ((c = nextc(p)) == '=' && !peek(p, '~') && !peek(p, '>') && 5409 6029 (!peek(p, '=') || (peek_n(p, '>', 1)))) { … … 5426 6046 if (IS_LABEL_POSSIBLE()) { 5427 6047 if (IS_LABEL_SUFFIX(0)) { 5428 p->lstate = EXPR_BEG; 5429 nextc(p); 6048 p->lstate = EXPR_END; 5430 6049 tokfix(p); 5431 pylval.id = intern _cstr(tok(p));5432 return t LABEL;6050 pylval.id = intern(tok(p), toklen(p)); 6051 return tIDENTIFIER; 5433 6052 } 5434 6053 } … … 5488 6107 } 5489 6108 { 5490 mrb_sym ident = intern _cstr(tok(p));6109 mrb_sym ident = intern(tok(p), toklen(p)); 5491 6110 5492 6111 pylval.id = ident; 5493 #if 0 5494 if (last_state != EXPR_DOT && islower(tok(p)[0]) && lvar_defined(ident)) { 6112 if (last_state != EXPR_DOT && ISLOWER(tok(p)[0]) && local_var_p(p, ident)) { 5495 6113 p->lstate = EXPR_END; 5496 6114 } 5497 #endif5498 6115 } 5499 6116 return result; … … 5524 6141 p->capture_errors = cxt->capture_errors; 5525 6142 p->no_optimize = cxt->no_optimize; 6143 p->on_eval = cxt->on_eval; 5526 6144 if (cxt->partial_hook) { 5527 6145 p->cxt = cxt; … … 5536 6154 5537 6155 if (!cxt) return; 5538 if ( (int)(intptr_t)p->tree->car!= NODE_SCOPE) return;6156 if (intn(p->tree->car) != NODE_SCOPE) return; 5539 6157 n0 = n = p->tree->cdr->car; 5540 6158 while (n) { … … 5559 6177 5560 6178 MRB_TRY(p->jmp) { 5561 int n ;6179 int n = 1; 5562 6180 5563 6181 p->cmd_start = TRUE; … … 5675 6293 { 5676 6294 if (s) { 5677 int len = strlen(s);6295 size_t len = strlen(s); 5678 6296 char *p = (char *)mrb_malloc(mrb, len + 1); 5679 6297 … … 5702 6320 5703 6321 sym = mrb_intern_cstr(p->mrb, f); 5704 p->filename = mrb_sym2name_len(p->mrb, sym, NULL);6322 p->filename_sym = sym; 5705 6323 p->lineno = (p->filename_table_length > 0)? 0 : 1; 5706 6324 5707 6325 for (i = 0; i < p->filename_table_length; ++i) { 5708 6326 if (p->filename_table[i] == sym) { 5709 p->current_filename_index = i;6327 p->current_filename_index = (int)i; 5710 6328 return; 5711 6329 } 5712 6330 } 5713 6331 6332 if (p->filename_table_length == UINT16_MAX) { 6333 yyerror(p, "too many files to compile"); 6334 return; 6335 } 5714 6336 p->current_filename_index = p->filename_table_length++; 5715 6337 5716 6338 new_table = (mrb_sym*)parser_palloc(p, sizeof(mrb_sym) * p->filename_table_length); 5717 6339 if (p->filename_table) { 5718 memmove(new_table, p->filename_table, sizeof(mrb_sym) * p-> filename_table_length);6340 memmove(new_table, p->filename_table, sizeof(mrb_sym) * p->current_filename_index); 5719 6341 } 5720 6342 p->filename_table = new_table; … … 5722 6344 } 5723 6345 5724 MRB_API char const*6346 MRB_API mrb_sym 5725 6347 mrb_parser_get_filename(struct mrb_parser_state* p, uint16_t idx) { 5726 if (idx >= p->filename_table_length) { return NULL; }6348 if (idx >= p->filename_table_length) return 0; 5727 6349 else { 5728 return mrb_sym2name_len(p->mrb, p->filename_table[idx], NULL);6350 return p->filename_table[idx]; 5729 6351 } 5730 6352 } … … 5747 6369 5748 6370 MRB_API parser_state* 5749 mrb_parse_nstring(mrb_state *mrb, const char *s, int len, mrbc_context *c)6371 mrb_parse_nstring(mrb_state *mrb, const char *s, size_t len, mrbc_context *c) 5750 6372 { 5751 6373 parser_state *p; … … 5778 6400 } 5779 6401 if (!p->tree || p->nerr) { 6402 if (c) c->parser_nerr = p->nerr; 5780 6403 if (p->capture_errors) { 5781 6404 char buf[256]; 5782 int n; 5783 5784 n = snprintf(buf, sizeof(buf), "line %d: %s\n", 5785 p->error_buffer[0].lineno, p->error_buffer[0].message); 5786 mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, n)); 6405 6406 strcpy(buf, "line "); 6407 dump_int(p->error_buffer[0].lineno, buf+5); 6408 strcat(buf, ": "); 6409 strncat(buf, p->error_buffer[0].message, sizeof(buf) - strlen(buf) - 1); 6410 mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, strlen(buf))); 5787 6411 mrb_parser_free(p); 5788 6412 return mrb_undef_value(); … … 5817 6441 } 5818 6442 } 5819 proc->target_class = target;6443 MRB_PROC_SET_TARGET_CLASS(proc, target); 5820 6444 if (mrb->c->ci) { 5821 6445 mrb->c->ci->target_class = target; … … 5841 6465 5842 6466 MRB_API mrb_value 5843 mrb_load_nstring_cxt(mrb_state *mrb, const char *s, int len, mrbc_context *c)6467 mrb_load_nstring_cxt(mrb_state *mrb, const char *s, size_t len, mrbc_context *c) 5844 6468 { 5845 6469 return mrb_load_exec(mrb, mrb_parse_nstring(mrb, s, len, c), c); … … 5847 6471 5848 6472 MRB_API mrb_value 5849 mrb_load_nstring(mrb_state *mrb, const char *s, int len)6473 mrb_load_nstring(mrb_state *mrb, const char *s, size_t len) 5850 6474 { 5851 6475 return mrb_load_nstring_cxt(mrb, s, len, NULL); … … 5885 6509 } 5886 6510 6511 static void 6512 dump_args(mrb_state *mrb, node *n, int offset) 6513 { 6514 if (n->car) { 6515 dump_prefix(n, offset+1); 6516 printf("mandatory args:\n"); 6517 dump_recur(mrb, n->car, offset+2); 6518 } 6519 n = n->cdr; 6520 if (n->car) { 6521 dump_prefix(n, offset+1); 6522 printf("optional args:\n"); 6523 { 6524 node *n2 = n->car; 6525 6526 while (n2) { 6527 dump_prefix(n2, offset+2); 6528 printf("%s=\n", mrb_sym_name(mrb, sym(n2->car->car))); 6529 mrb_parser_dump(mrb, n2->car->cdr, offset+3); 6530 n2 = n2->cdr; 6531 } 6532 } 6533 } 6534 n = n->cdr; 6535 if (n->car) { 6536 dump_prefix(n, offset+1); 6537 printf("rest=*%s\n", mrb_sym_name(mrb, sym(n->car))); 6538 } 6539 n = n->cdr; 6540 if (n->car) { 6541 dump_prefix(n, offset+1); 6542 printf("post mandatory args:\n"); 6543 dump_recur(mrb, n->car, offset+2); 6544 } 6545 6546 n = n->cdr; 6547 if (n) { 6548 mrb_assert(intn(n->car) == NODE_ARGS_TAIL); 6549 mrb_parser_dump(mrb, n, offset); 6550 } 6551 } 6552 6553 /* 6554 * This function restores the GC arena on return. 6555 * For this reason, if a process that further generates an object is 6556 * performed at the caller, the string pointer returned as the return 6557 * value may become invalid. 6558 */ 6559 static const char* 6560 str_dump(mrb_state *mrb, const char *str, int len) 6561 { 6562 mrb_int ai = mrb_gc_arena_save(mrb); 6563 mrb_value s; 6564 # if INT_MAX > MRB_INT_MAX / 4 6565 /* check maximum length with "\xNN" charactor */ 6566 if (len > MRB_INT_MAX / 4) { 6567 len = MRB_INT_MAX / 4; 6568 } 6569 # endif 6570 s = mrb_str_new(mrb, str, (mrb_int)len); 6571 s = mrb_str_dump(mrb, s); 6572 mrb_gc_arena_restore(mrb, ai); 6573 return RSTRING_PTR(s); 6574 } 5887 6575 #endif 5888 6576 … … 5896 6584 again: 5897 6585 dump_prefix(tree, offset); 5898 nodetype = (int)(intptr_t)tree->car;6586 nodetype = intn(tree->car); 5899 6587 tree = tree->cdr; 5900 6588 switch (nodetype) { … … 5956 6644 5957 6645 case NODE_LAMBDA: 5958 printf("NODE_BLOCK:\n"); 6646 printf("NODE_LAMBDA:\n"); 6647 dump_prefix(tree, offset); 5959 6648 goto block; 5960 6649 … … 5964 6653 tree = tree->cdr; 5965 6654 if (tree->car) { 5966 node *n = tree->car; 5967 5968 if (n->car) { 5969 dump_prefix(n, offset+1); 5970 printf("mandatory args:\n"); 5971 dump_recur(mrb, n->car, offset+2); 5972 } 5973 n = n->cdr; 5974 if (n->car) { 5975 dump_prefix(n, offset+1); 5976 printf("optional args:\n"); 5977 { 5978 node *n2 = n->car; 5979 5980 while (n2) { 5981 dump_prefix(n2, offset+2); 5982 printf("%s=", mrb_sym2name(mrb, sym(n2->car->car))); 5983 mrb_parser_dump(mrb, n2->car->cdr, 0); 5984 n2 = n2->cdr; 5985 } 5986 } 5987 } 5988 n = n->cdr; 5989 if (n->car) { 5990 dump_prefix(n, offset+1); 5991 printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car))); 5992 } 5993 n = n->cdr; 5994 if (n->car) { 5995 dump_prefix(n, offset+1); 5996 printf("post mandatory args:\n"); 5997 dump_recur(mrb, n->car, offset+2); 5998 } 5999 if (n->cdr) { 6000 dump_prefix(n, offset+1); 6001 printf("blk=&%s\n", mrb_sym2name(mrb, sym(n->cdr))); 6002 } 6655 dump_args(mrb, tree->car, offset+1); 6003 6656 } 6004 6657 dump_prefix(tree, offset+1); … … 6123 6776 if (n2->car) { 6124 6777 if (!first_lval) printf(", "); 6125 printf("%s", mrb_sym 2name(mrb, sym(n2->car)));6778 printf("%s", mrb_sym_name(mrb, sym(n2->car))); 6126 6779 first_lval = FALSE; 6127 6780 } … … 6151 6804 dump_prefix(tree, offset+1); 6152 6805 printf("method='%s' (%d)\n", 6153 mrb_sym 2name(mrb, sym(tree->cdr->car)),6154 (int)(intptr_t)tree->cdr->car);6806 mrb_sym_dump(mrb, sym(tree->cdr->car)), 6807 intn(tree->cdr->car)); 6155 6808 tree = tree->cdr->cdr->car; 6156 6809 if (tree) { … … 6182 6835 mrb_parser_dump(mrb, tree->car, offset+1); 6183 6836 dump_prefix(tree, offset+1); 6184 printf("::%s\n", mrb_sym 2name(mrb, sym(tree->cdr)));6837 printf("::%s\n", mrb_sym_name(mrb, sym(tree->cdr))); 6185 6838 break; 6186 6839 6187 6840 case NODE_COLON3: 6188 printf("NODE_COLON3: ::%s\n", mrb_sym 2name(mrb, sym(tree)));6841 printf("NODE_COLON3: ::%s\n", mrb_sym_name(mrb, sym(tree))); 6189 6842 break; 6190 6843 … … 6196 6849 case NODE_HASH: 6197 6850 printf("NODE_HASH:\n"); 6851 while (tree) { 6852 dump_prefix(tree, offset+1); 6853 printf("key:\n"); 6854 mrb_parser_dump(mrb, tree->car->car, offset+2); 6855 dump_prefix(tree, offset+1); 6856 printf("value:\n"); 6857 mrb_parser_dump(mrb, tree->car->cdr, offset+2); 6858 tree = tree->cdr; 6859 } 6860 break; 6861 6862 case NODE_KW_HASH: 6863 printf("NODE_KW_HASH:\n"); 6198 6864 while (tree) { 6199 6865 dump_prefix(tree, offset+1); … … 6269 6935 tree = tree->cdr; 6270 6936 dump_prefix(tree, offset+1); 6271 printf("op='%s' (%d)\n", mrb_sym 2name(mrb, sym(tree->car)), (int)(intptr_t)tree->car);6937 printf("op='%s' (%d)\n", mrb_sym_name(mrb, sym(tree->car)), intn(tree->car)); 6272 6938 tree = tree->cdr; 6273 6939 mrb_parser_dump(mrb, tree->car, offset+1); … … 6321 6987 6322 6988 case NODE_LVAR: 6323 printf("NODE_LVAR %s\n", mrb_sym 2name(mrb, sym(tree)));6989 printf("NODE_LVAR %s\n", mrb_sym_name(mrb, sym(tree))); 6324 6990 break; 6325 6991 6326 6992 case NODE_GVAR: 6327 printf("NODE_GVAR %s\n", mrb_sym 2name(mrb, sym(tree)));6993 printf("NODE_GVAR %s\n", mrb_sym_name(mrb, sym(tree))); 6328 6994 break; 6329 6995 6330 6996 case NODE_IVAR: 6331 printf("NODE_IVAR %s\n", mrb_sym 2name(mrb, sym(tree)));6997 printf("NODE_IVAR %s\n", mrb_sym_name(mrb, sym(tree))); 6332 6998 break; 6333 6999 6334 7000 case NODE_CVAR: 6335 printf("NODE_CVAR %s\n", mrb_sym2name(mrb, sym(tree))); 7001 printf("NODE_CVAR %s\n", mrb_sym_name(mrb, sym(tree))); 7002 break; 7003 7004 case NODE_NVAR: 7005 printf("NODE_NVAR %d\n", intn(tree)); 6336 7006 break; 6337 7007 6338 7008 case NODE_CONST: 6339 printf("NODE_CONST %s\n", mrb_sym 2name(mrb, sym(tree)));7009 printf("NODE_CONST %s\n", mrb_sym_name(mrb, sym(tree))); 6340 7010 break; 6341 7011 … … 6351 7021 6352 7022 case NODE_BACK_REF: 6353 printf("NODE_BACK_REF: $%c\n", (int)(intptr_t)tree);7023 printf("NODE_BACK_REF: $%c\n", intn(tree)); 6354 7024 break; 6355 7025 6356 7026 case NODE_NTH_REF: 6357 printf("NODE_NTH_REF: $% " MRB_PRId "\n", (mrb_int)(intptr_t)tree);7027 printf("NODE_NTH_REF: $%d\n", intn(tree)); 6358 7028 break; 6359 7029 6360 7030 case NODE_ARG: 6361 printf("NODE_ARG %s\n", mrb_sym 2name(mrb, sym(tree)));7031 printf("NODE_ARG %s\n", mrb_sym_name(mrb, sym(tree))); 6362 7032 break; 6363 7033 … … 6368 7038 6369 7039 case NODE_INT: 6370 printf("NODE_INT %s base %d\n", (char*)tree->car, (int)(intptr_t)tree->cdr->car);7040 printf("NODE_INT %s base %d\n", (char*)tree->car, intn(tree->cdr->car)); 6371 7041 break; 6372 7042 … … 6376 7046 6377 7047 case NODE_NEGATE: 6378 printf("NODE_NEGATE \n");7048 printf("NODE_NEGATE:\n"); 6379 7049 mrb_parser_dump(mrb, tree, offset+1); 6380 7050 break; 6381 7051 6382 7052 case NODE_STR: 6383 printf("NODE_STR \"%s\" len %d\n", (char*)tree->car, (int)(intptr_t)tree->cdr);7053 printf("NODE_STR %s len %d\n", str_dump(mrb, (char*)tree->car, intn(tree->cdr)), intn(tree->cdr)); 6384 7054 break; 6385 7055 6386 7056 case NODE_DSTR: 6387 printf("NODE_DSTR \n");7057 printf("NODE_DSTR:\n"); 6388 7058 dump_recur(mrb, tree, offset+1); 6389 7059 break; 6390 7060 6391 7061 case NODE_XSTR: 6392 printf("NODE_XSTR \"%s\" len %d\n", (char*)tree->car, (int)(intptr_t)tree->cdr);7062 printf("NODE_XSTR %s len %d\n", str_dump(mrb, (char*)tree->car, intn(tree->cdr)), intn(tree->cdr)); 6393 7063 break; 6394 7064 6395 7065 case NODE_DXSTR: 6396 printf("NODE_DXSTR \n");7066 printf("NODE_DXSTR:\n"); 6397 7067 dump_recur(mrb, tree, offset+1); 6398 7068 break; … … 6403 7073 6404 7074 case NODE_DREGX: 6405 printf("NODE_DREGX \n");7075 printf("NODE_DREGX:\n"); 6406 7076 dump_recur(mrb, tree->car, offset+1); 6407 7077 dump_prefix(tree, offset); … … 6418 7088 6419 7089 case NODE_SYM: 6420 printf("NODE_SYM :%s (%d)\n", mrb_sym2name(mrb, sym(tree)), 6421 (int)(intptr_t)tree); 7090 printf("NODE_SYM :%s (%d)\n", mrb_sym_dump(mrb, sym(tree)), 7091 intn(tree)); 7092 break; 7093 7094 case NODE_DSYM: 7095 printf("NODE_DSYM:\n"); 7096 mrb_parser_dump(mrb, tree, offset+1); 7097 break; 7098 7099 case NODE_WORDS: 7100 printf("NODE_WORDS:\n"); 7101 dump_recur(mrb, tree, offset+1); 7102 break; 7103 7104 case NODE_SYMBOLS: 7105 printf("NODE_SYMBOLS:\n"); 7106 dump_recur(mrb, tree, offset+1); 7107 break; 7108 7109 case NODE_LITERAL_DELIM: 7110 printf("NODE_LITERAL_DELIM\n"); 6422 7111 break; 6423 7112 … … 6440 7129 case NODE_ALIAS: 6441 7130 printf("NODE_ALIAS %s %s:\n", 6442 mrb_sym 2name(mrb, sym(tree->car)),6443 mrb_sym 2name(mrb, sym(tree->cdr)));7131 mrb_sym_dump(mrb, sym(tree->car)), 7132 mrb_sym_dump(mrb, sym(tree->cdr))); 6444 7133 break; 6445 7134 … … 6449 7138 node *t = tree; 6450 7139 while (t) { 6451 printf(" %s", mrb_sym 2name(mrb, sym(t->car)));7140 printf(" %s", mrb_sym_dump(mrb, sym(t->car))); 6452 7141 t = t->cdr; 6453 7142 } … … 6460 7149 if (tree->car->car == (node*)0) { 6461 7150 dump_prefix(tree, offset+1); 6462 printf(":%s\n", mrb_sym 2name(mrb, sym(tree->car->cdr)));7151 printf(":%s\n", mrb_sym_name(mrb, sym(tree->car->cdr))); 6463 7152 } 6464 7153 else if (tree->car->car == (node*)1) { 6465 7154 dump_prefix(tree, offset+1); 6466 printf("::%s\n", mrb_sym 2name(mrb, sym(tree->car->cdr)));7155 printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr))); 6467 7156 } 6468 7157 else { 6469 7158 mrb_parser_dump(mrb, tree->car->car, offset+1); 6470 7159 dump_prefix(tree, offset+1); 6471 printf("::%s\n", mrb_sym 2name(mrb, sym(tree->car->cdr)));7160 printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr))); 6472 7161 } 6473 7162 if (tree->cdr->car) { … … 6485 7174 if (tree->car->car == (node*)0) { 6486 7175 dump_prefix(tree, offset+1); 6487 printf(":%s\n", mrb_sym 2name(mrb, sym(tree->car->cdr)));7176 printf(":%s\n", mrb_sym_name(mrb, sym(tree->car->cdr))); 6488 7177 } 6489 7178 else if (tree->car->car == (node*)1) { 6490 7179 dump_prefix(tree, offset+1); 6491 printf("::%s\n", mrb_sym 2name(mrb, sym(tree->car->cdr)));7180 printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr))); 6492 7181 } 6493 7182 else { 6494 7183 mrb_parser_dump(mrb, tree->car->car, offset+1); 6495 7184 dump_prefix(tree, offset+1); 6496 printf("::%s\n", mrb_sym 2name(mrb, sym(tree->car->cdr)));7185 printf("::%s\n", mrb_sym_name(mrb, sym(tree->car->cdr))); 6497 7186 } 6498 7187 dump_prefix(tree, offset+1); … … 6512 7201 printf("NODE_DEF:\n"); 6513 7202 dump_prefix(tree, offset+1); 6514 printf("%s\n", mrb_sym 2name(mrb, sym(tree->car)));7203 printf("%s\n", mrb_sym_dump(mrb, sym(tree->car))); 6515 7204 tree = tree->cdr; 6516 7205 { … … 6525 7214 if (n2->car) { 6526 7215 if (!first_lval) printf(", "); 6527 printf("%s", mrb_sym 2name(mrb, sym(n2->car)));7216 printf("%s", mrb_sym_name(mrb, sym(n2->car))); 6528 7217 first_lval = FALSE; 6529 7218 } … … 6535 7224 tree = tree->cdr; 6536 7225 if (tree->car) { 6537 node *n = tree->car; 6538 6539 if (n->car) { 6540 dump_prefix(n, offset+1); 6541 printf("mandatory args:\n"); 6542 dump_recur(mrb, n->car, offset+2); 6543 } 6544 n = n->cdr; 6545 if (n->car) { 6546 dump_prefix(n, offset+1); 6547 printf("optional args:\n"); 6548 { 6549 node *n2 = n->car; 6550 6551 while (n2) { 6552 dump_prefix(n2, offset+2); 6553 printf("%s=", mrb_sym2name(mrb, sym(n2->car->car))); 6554 mrb_parser_dump(mrb, n2->car->cdr, 0); 6555 n2 = n2->cdr; 6556 } 6557 } 6558 } 6559 n = n->cdr; 6560 if (n->car) { 6561 dump_prefix(n, offset+1); 6562 printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car))); 6563 } 6564 n = n->cdr; 6565 if (n->car) { 6566 dump_prefix(n, offset+1); 6567 printf("post mandatory args:\n"); 6568 dump_recur(mrb, n->car, offset+2); 6569 } 6570 if (n->cdr) { 6571 dump_prefix(n, offset+1); 6572 printf("blk=&%s\n", mrb_sym2name(mrb, sym(n->cdr))); 6573 } 7226 dump_args(mrb, tree->car, offset); 6574 7227 } 6575 7228 mrb_parser_dump(mrb, tree->cdr->car, offset+1); … … 6581 7234 tree = tree->cdr; 6582 7235 dump_prefix(tree, offset+1); 6583 printf(":%s\n", mrb_sym 2name(mrb, sym(tree->car)));7236 printf(":%s\n", mrb_sym_dump(mrb, sym(tree->car))); 6584 7237 tree = tree->cdr->cdr; 6585 7238 if (tree->car) { 6586 node *n = tree->car; 6587 6588 if (n->car) { 6589 dump_prefix(n, offset+1); 6590 printf("mandatory args:\n"); 6591 dump_recur(mrb, n->car, offset+2); 6592 } 6593 n = n->cdr; 6594 if (n->car) { 6595 dump_prefix(n, offset+1); 6596 printf("optional args:\n"); 6597 { 6598 node *n2 = n->car; 6599 6600 while (n2) { 6601 dump_prefix(n2, offset+2); 6602 printf("%s=", mrb_sym2name(mrb, sym(n2->car->car))); 6603 mrb_parser_dump(mrb, n2->car->cdr, 0); 6604 n2 = n2->cdr; 6605 } 6606 } 6607 } 6608 n = n->cdr; 6609 if (n->car) { 6610 dump_prefix(n, offset+1); 6611 printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car))); 6612 } 6613 n = n->cdr; 6614 if (n->car) { 6615 dump_prefix(n, offset+1); 6616 printf("post mandatory args:\n"); 6617 dump_recur(mrb, n->car, offset+2); 6618 } 6619 n = n->cdr; 6620 if (n) { 6621 dump_prefix(n, offset+1); 6622 printf("blk=&%s\n", mrb_sym2name(mrb, sym(n))); 6623 } 7239 dump_args(mrb, tree->car, offset+1); 6624 7240 } 6625 7241 tree = tree->cdr; … … 6637 7253 break; 6638 7254 7255 case NODE_ARGS_TAIL: 7256 printf("NODE_ARGS_TAIL:\n"); 7257 { 7258 node *kws = tree->car; 7259 7260 while (kws) { 7261 mrb_parser_dump(mrb, kws->car, offset+1); 7262 kws = kws->cdr; 7263 } 7264 } 7265 tree = tree->cdr; 7266 if (tree->car) { 7267 mrb_assert(intn(tree->car->car) == NODE_KW_REST_ARGS); 7268 mrb_parser_dump(mrb, tree->car, offset+1); 7269 } 7270 tree = tree->cdr; 7271 if (tree->car) { 7272 dump_prefix(tree, offset+1); 7273 printf("block='%s'\n", mrb_sym_name(mrb, sym(tree->car))); 7274 } 7275 break; 7276 7277 case NODE_KW_ARG: 7278 printf("NODE_KW_ARG %s:\n", mrb_sym_name(mrb, sym(tree->car))); 7279 mrb_parser_dump(mrb, tree->cdr->car, offset + 1); 7280 break; 7281 7282 case NODE_KW_REST_ARGS: 7283 printf("NODE_KW_REST_ARGS %s\n", mrb_sym_name(mrb, sym(tree))); 7284 break; 7285 6639 7286 default: 6640 7287 printf("node type: %d (0x%x)\n", nodetype, (unsigned)nodetype); -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-compiler/mrbgem.rake
r331 r439 24 24 end 25 25 end 26 file objfile("#{current_build_dir}/core/y.tab") => lex_def27 26 28 27 # Parser 29 file "#{current_build_dir}/core/y.tab.c" => ["#{current_dir}/core/parse.y"] do |t| 28 file "#{current_build_dir}/core/y.tab.c" => ["#{current_dir}/core/parse.y", lex_def] do |t| 29 mkdir_p File.dirname t.name 30 30 yacc.run t.name, t.prerequisites.first 31 31 end … … 36 36 end 37 37 38 file libfile("#{build.build_dir}/lib/libmruby_core")=> core_objs38 file build.libmruby_core_static => core_objs 39 39 build.libmruby << core_objs 40 40 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-enum-ext/mrblib/enum.rb
r331 r439 14 14 15 15 def drop(n) 16 raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)16 n = n.__to_int 17 17 raise ArgumentError, "attempt to drop negative size" if n < 0 18 18 19 n = n.to_int20 19 ary = [] 21 20 self.each {|*val| n == 0 ? ary << val.__svalue : n -= 1 } … … 58 57 59 58 def take(n) 60 raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)61 i = n.to_i nt59 n = n.__to_int 60 i = n.to_i 62 61 raise ArgumentError, "attempt to take negative size" if i < 0 63 62 ary = [] … … 114 113 115 114 def each_cons(n, &block) 116 raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)115 n = n.__to_int 117 116 raise ArgumentError, "invalid size" if n <= 0 118 117 119 118 return to_enum(:each_cons,n) unless block 120 119 ary = [] 121 n = n.to_i nt120 n = n.to_i 122 121 self.each do |*val| 123 122 ary.shift if ary.size == n … … 142 141 143 142 def each_slice(n, &block) 144 raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)143 n = n.__to_int 145 144 raise ArgumentError, "invalid slice size" if n <= 0 146 145 147 146 return to_enum(:each_slice,n) unless block 148 147 ary = [] 149 n = n.to_i nt148 n = n.to_i 150 149 self.each do |*val| 151 150 ary << val.__svalue … … 202 201 } 203 202 if ary.size > 1 204 __sort_sub__(ary, ::Array.new(ary.size), 0, 0, ary.size - 1) do |a,b| 205 a <=> b 206 end 203 ary.sort! 207 204 end 208 205 ary.collect{|e,i| orig[i]} 209 206 end 210 207 211 NONE = Object.new212 208 ## 213 209 # call-seq: … … 226 222 return nil 227 223 when 1 228 n = args[0] 229 raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int) 230 i = n.to_int 224 i = args[0].__to_int 231 225 raise ArgumentError, "attempt to take negative size" if i < 0 232 226 ary = [] … … 452 446 # call-seq: 453 447 # enum.none? [{ |obj| block }] -> true or false 448 # enum.none?(pattern) -> true or false 454 449 # 455 450 # Passes each element of the collection to the given block. The method … … 458 453 # <code>true</code> only if none of the collection members is true. 459 454 # 455 # If a pattern is supplied instead, the method returns whether 456 # <code>pattern === element</code> for none of the collection members. 457 # 460 458 # %w(ant bear cat).none? { |word| word.length == 5 } #=> true 461 459 # %w(ant bear cat).none? { |word| word.length >= 4 } #=> false 460 # %w{ant bear cat}.none?(/d/) #=> true 461 # [1, 3.14, 42].none?(Float) #=> false 462 462 # [].none? #=> true 463 463 # [nil, false].none? #=> true 464 464 # [nil, true].none? #=> false 465 465 466 def none?(&block) 467 if block 466 def none?(pat=NONE, &block) 467 if pat != NONE 468 self.each do |*val| 469 return false if pat === val.__svalue 470 end 471 elsif block 468 472 self.each do |*val| 469 473 return false if block.call(*val) … … 480 484 # call-seq: 481 485 # enum.one? [{ |obj| block }] -> true or false 486 # enum.one?(pattern) -> true or false 482 487 # 483 488 # Passes each element of the collection to the given block. The method … … 487 492 # true. 488 493 # 494 # If a pattern is supplied instead, the method returns whether 495 # <code>pattern === element</code> for exactly one collection member. 496 # 489 497 # %w(ant bear cat).one? { |word| word.length == 4 } #=> true 490 498 # %w(ant bear cat).one? { |word| word.length > 4 } #=> false 491 499 # %w(ant bear cat).one? { |word| word.length < 4 } #=> false 500 # %w{ant bear cat}.one?(/t/) #=> false 492 501 # [nil, true, 99].one? #=> false 493 502 # [nil, true, false].one? #=> true 494 # 495 496 def one?(&block) 503 # [ nil, true, 99 ].one?(Integer) #=> true 504 # [].one? #=> false 505 506 def one?(pat=NONE, &block) 497 507 count = 0 498 if block 508 if pat!=NONE 509 self.each do |*val| 510 count += 1 if pat === val.__svalue 511 return false if count > 1 512 end 513 elsif block 499 514 self.each do |*val| 500 515 count += 1 if block.call(*val) … … 511 526 end 512 527 528 # ISO 15.3.2.2.1 529 # call-seq: 530 # enum.all? [{ |obj| block } ] -> true or false 531 # enum.all?(pattern) -> true or false 532 # 533 # Passes each element of the collection to the given block. The method 534 # returns <code>true</code> if the block never returns 535 # <code>false</code> or <code>nil</code>. If the block is not given, 536 # Ruby adds an implicit block of <code>{ |obj| obj }</code> which will 537 # cause #all? to return +true+ when none of the collection members are 538 # +false+ or +nil+. 539 # 540 # If a pattern is supplied instead, the method returns whether 541 # <code>pattern === element</code> for every collection member. 542 # 543 # %w[ant bear cat].all? { |word| word.length >= 3 } #=> true 544 # %w[ant bear cat].all? { |word| word.length >= 4 } #=> false 545 # %w[ant bear cat].all?(/t/) #=> false 546 # [1, 2i, 3.14].all?(Numeric) #=> true 547 # [nil, true, 99].all? #=> false 548 # 549 def all?(pat=NONE, &block) 550 if pat != NONE 551 self.each{|*val| return false unless pat === val.__svalue} 552 elsif block 553 self.each{|*val| return false unless block.call(*val)} 554 else 555 self.each{|*val| return false unless val.__svalue} 556 end 557 true 558 end 559 560 # ISO 15.3.2.2.2 561 # call-seq: 562 # enum.any? [{ |obj| block }] -> true or false 563 # enum.any?(pattern) -> true or false 564 # 565 # Passes each element of the collection to the given block. The method 566 # returns <code>true</code> if the block ever returns a value other 567 # than <code>false</code> or <code>nil</code>. If the block is not 568 # given, Ruby adds an implicit block of <code>{ |obj| obj }</code> that 569 # will cause #any? to return +true+ if at least one of the collection 570 # members is not +false+ or +nil+. 571 # 572 # If a pattern is supplied instead, the method returns whether 573 # <code>pattern === element</code> for any collection member. 574 # 575 # %w[ant bear cat].any? { |word| word.length >= 3 } #=> true 576 # %w[ant bear cat].any? { |word| word.length >= 4 } #=> true 577 # %w[ant bear cat].any?(/d/) #=> false 578 # [nil, true, 99].any?(Integer) #=> true 579 # [nil, true, 99].any? #=> true 580 # [].any? #=> false 581 # 582 def any?(pat=NONE, &block) 583 if pat != NONE 584 self.each{|*val| return true if pat === val.__svalue} 585 elsif block 586 self.each{|*val| return true if block.call(*val)} 587 else 588 self.each{|*val| return true if val.__svalue} 589 end 590 false 591 end 592 513 593 ## 514 594 # call-seq: … … 525 605 # 526 606 527 def each_with_object(obj=nil, &block) 528 raise ArgumentError, "wrong number of arguments (0 for 1)" if obj.nil? 529 607 def each_with_object(obj, &block) 530 608 return to_enum(:each_with_object, obj) unless block 531 609 … … 592 670 n = -1 593 671 else 594 unless nv.respond_to?(:to_int) 595 raise TypeError, "no implicit conversion of #{nv.class} into Integer" 596 end 597 n = nv.to_int 598 unless n.kind_of?(Integer) 599 raise TypeError, "no implicit conversion of #{nv.class} into Integer" 600 end 672 n = nv.__to_int 601 673 return nil if n <= 0 602 674 end … … 657 729 # call-seq: 658 730 # enum.zip(arg, ...) -> an_array_of_array 731 # enum.zip(arg, ...) { |arr| block } -> nil 659 732 # 660 733 # Takes one element from <i>enum</i> and merges corresponding … … 663 736 # count of arguments. The length of the resulting sequence will be 664 737 # <code>enum#size</code>. If the size of any argument is less than 665 # <code>enum#size</code>, <code>nil</code> values are supplied. 666 # 667 668 def zip(*arg) 669 ary = [] 670 arg = arg.map{|a|a.to_a} 738 # <code>enum#size</code>, <code>nil</code> values are supplied. If 739 # a block is given, it is invoked for each output array, otherwise 740 # an array of arrays is returned. 741 # 742 # a = [ 4, 5, 6 ] 743 # b = [ 7, 8, 9 ] 744 # 745 # a.zip(b) #=> [[4, 7], [5, 8], [6, 9]] 746 # [1, 2, 3].zip(a, b) #=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]] 747 # [1, 2].zip(a, b) #=> [[1, 4, 7], [2, 5, 8]] 748 # a.zip([1, 2], [8]) #=> [[4, 1, 8], [5, 2, nil], [6, nil, nil]] 749 # 750 # c = [] 751 # a.zip(b) { |x, y| c << x + y } #=> nil 752 # c #=> [11, 13, 15] 753 # 754 755 def zip(*arg, &block) 756 result = block ? nil : [] 757 arg = arg.map do |a| 758 unless a.respond_to?(:to_a) 759 raise TypeError, "wrong argument type #{a.class} (must respond to :to_a)" 760 end 761 a.to_a 762 end 763 671 764 i = 0 672 765 self.each do |*val| … … 678 771 idx += 1 679 772 end 680 ary.push(a)681 773 i += 1 682 end 683 ary 774 if result.nil? 775 block.call(a) 776 else 777 result.push(a) 778 end 779 end 780 result 684 781 end 685 782 … … 695 792 # 696 793 697 def to_h 794 def to_h(&blk) 698 795 h = {} 699 self.each do |*v| 700 v = v.__svalue 701 raise TypeError, "wrong element type #{v.class} (expected Array)" unless v.is_a? Array 702 raise ArgumentError, "element has wrong array length (expected 2, was #{v.size})" if v.size != 2 703 h[v[0]] = v[1] 796 if blk 797 self.each do |v| 798 v = blk.call(v) 799 raise TypeError, "wrong element type #{v.class} (expected Array)" unless v.is_a? Array 800 raise ArgumentError, "element has wrong array length (expected 2, was #{v.size})" if v.size != 2 801 h[v[0]] = v[1] 802 end 803 else 804 self.each do |*v| 805 v = v.__svalue 806 raise TypeError, "wrong element type #{v.class} (expected Array)" unless v.is_a? Array 807 raise ArgumentError, "element has wrong array length (expected 2, was #{v.size})" if v.size != 2 808 h[v[0]] = v[1] 809 end 704 810 end 705 811 h 706 812 end 707 813 708 def nil.to_h 709 {} 814 def uniq(&block) 815 hash = {} 816 if block 817 self.each do|*v| 818 v = v.__svalue 819 hash[block.call(v)] ||= v 820 end 821 else 822 self.each do|*v| 823 v = v.__svalue 824 hash[v] ||= v 825 end 826 end 827 hash.values 828 end 829 830 def filter_map(&blk) 831 return to_enum(:filter_map) unless blk 832 833 ary = [] 834 self.each do |x| 835 x = blk.call(x) 836 ary.push x if x 837 end 838 ary 839 end 840 841 alias filter select 842 843 ## 844 # call-seq: 845 # enum.tally -> a_hash 846 # 847 # Tallys the collection. Returns a hash where the keys are the 848 # elements and the values are numbers of elements in the collection 849 # that correspond to the key. 850 # 851 # ["a", "b", "c", "b"].tally #=> {"a"=>1, "b"=>2, "c"=>1} 852 def tally 853 hash = {} 854 self.each do |x| 855 hash[x] = (hash[x]||0)+1 856 end 857 hash 710 858 end 711 859 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-enum-ext/test/enum.rb
r331 r439 101 101 assert_true %w(ant bear cat).none? { |word| word.length == 5 } 102 102 assert_false %w(ant bear cat).none? { |word| word.length >= 4 } 103 assert_false [1, 3.14, 42].none?(Float) 103 104 assert_true [].none? 104 105 assert_true [nil, false].none? … … 110 111 assert_false %w(ant bear cat).one? { |word| word.length > 4 } 111 112 assert_false %w(ant bear cat).one? { |word| word.length < 4 } 113 assert_true [1, 3.14, 42].one?(Float) 112 114 assert_false [nil, true, 99].one? 113 115 assert_true [nil, true, false].one? 116 assert_true [ nil, true, 99 ].one?(Integer) 117 assert_false [].one? 118 end 119 120 assert("Enumerable#all? (enhancement)") do 121 assert_false [1, 2, 3.14].all?(Integer) 122 assert_true [1, 2, 3.14].all?(Numeric) 123 end 124 125 assert("Enumerable#any? (enhancement)") do 126 assert_false [1, 2, 3].all?(Float) 127 assert_true [nil, true, 99].any?(Integer) 114 128 end 115 129 116 130 assert("Enumerable#each_with_object") do 117 assert_ true[2, 4, 6, 8, 10, 12, 14, 16, 18, 20], (1..10).each_with_object([]) { |i, a| a << i*2 }131 assert_equal [2, 4, 6, 8, 10, 12, 14, 16, 18, 20], (1..10).each_with_object([]) { |i, a| a << i*2 } 118 132 assert_raise(ArgumentError) { (1..10).each_with_object() { |i, a| a << i*2 } } 119 133 end … … 122 136 r = (1..3) 123 137 a = [] 124 assert_ equal (1..3), r.reverse_each { |v| a << v }138 assert_same r, r.reverse_each { |v| a << v } 125 139 assert_equal [3, 2, 1], a 126 140 end … … 153 167 assert_equal [[1, 4, 7], [2, 5, 8]], [1, 2].zip(a, b) 154 168 assert_equal [[4, 1, 8], [5, 2, nil], [6, nil, nil]], a.zip([1, 2], [8]) 169 170 ret = [] 171 assert_equal nil, a.zip([1, 2], [8]) { |i| ret << i } 172 assert_equal [[4, 1, 8], [5, 2, nil], [6, nil, nil]], ret 173 174 assert_raise(TypeError) { [1].zip(1) } 155 175 end 156 176 … … 167 187 assert_equal Hash, h.class 168 188 assert_equal h0, h 169 # mruby-enum-ext also provides nil.to_h 170 assert_equal Hash.new, nil.to_h 189 assert_equal({1=>4,3=>8}, c.new.to_h{|k,v|[k,v*2]}) 171 190 end 191 192 assert("Enumerable#filter_map") do 193 assert_equal [4, 8, 12, 16, 20], (1..10).filter_map{|i| i * 2 if i%2==0} 194 end 195 196 assert("Enumerable#tally") do 197 assert_equal({"a"=>1, "b"=>2, "c"=>1}, ["a", "b", "c", "b"].tally) 198 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-enum-lazy/mrblib/lazy.rb
r331 r439 44 44 45 45 def to_enum(meth=:each, *args, &block) 46 unless self.respond_to?(meth) 47 raise ArgumentError, "undefined method #{meth}" 48 end 46 49 lz = Lazy.new(self, &block) 47 50 lz.obj = self … … 70 73 def reject(&block) 71 74 Lazy.new(self){|yielder, val| 72 if notblock.call(val)75 unless block.call(val) 73 76 yielder << val 74 77 end … … 156 159 end 157 160 161 def uniq(&block) 162 hash = {} 163 Lazy.new(self){|yielder, val| 164 if block 165 v = block.call(val) 166 else 167 v = val 168 end 169 unless hash.include?(v) 170 yielder << val 171 hash[v] = val 172 end 173 } 174 end 175 158 176 alias force to_a 159 177 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-enum-lazy/test/lazy.rb
r331 r439 41 41 end 42 42 43 assert("Enum rator::Lazy#to_enum") do43 assert("Enumerator::Lazy#to_enum") do 44 44 lazy_enum = (0..Float::INFINITY).lazy.to_enum(:each_slice, 2) 45 45 assert_kind_of Enumerator::Lazy, lazy_enum -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-enumerator/mrbgem.rake
r321 r439 3 3 spec.author = 'mruby developers' 4 4 spec.add_dependency('mruby-fiber', :core => 'mruby-fiber') 5 spec.add_dependency 'mruby-enum-ext', :core => 'mruby-enum-ext'6 5 spec.summary = 'Enumerator class' 7 6 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-enumerator/mrblib/enumerator.rb
r331 r439 90 90 91 91 ## 92 # @overload initialize(size = nil, &block)93 92 # @overload initialize(obj, method = :each, *args) 94 93 # … … 110 109 # p fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] 111 110 # 112 def initialize(obj=nil, meth=:each, *args, &block) 113 if block_given? 111 # In the second, deprecated, form, a generated Enumerator iterates over the 112 # given object using the given method with the given arguments passed. This 113 # form is left only for internal use. 114 # 115 # Use of this form is discouraged. Use Kernel#enum_for or Kernel#to_enum 116 # instead. 117 def initialize(obj=NONE, meth=:each, *args, &block) 118 if block 114 119 obj = Generator.new(&block) 115 els e116 raise ArgumentError unless obj120 elsif obj == NONE 121 raise ArgumentError, "wrong number of arguments (given 0, expected 1+)" 117 122 end 118 123 119 124 @obj = obj 120 125 @meth = meth 121 @args = args .dup126 @args = args 122 127 @fib = nil 123 128 @dst = nil … … 126 131 @stop_exc = false 127 132 end 128 attr_accessor :obj, :meth, :args , :fib129 private :obj, :meth, :args,:fib133 attr_accessor :obj, :meth, :args 134 attr_reader :fib 130 135 131 136 def initialize_copy(obj) … … 152 157 # +offset+:: the starting index to use 153 158 # 154 def with_index(offset=0) 155 return to_enum :with_index, offset unless block_given? 156 offset = if offset.nil? 157 0 158 elsif offset.respond_to?(:to_int) 159 offset.to_int 159 def with_index(offset=0, &block) 160 return to_enum :with_index, offset unless block 161 162 if offset.nil? 163 offset = 0 160 164 else 161 raise TypeError, "no implicit conversion of #{offset.class} into Integer"165 offset = offset.__to_int 162 166 end 163 167 … … 165 169 enumerator_block_call do |*i| 166 170 n += 1 167 yieldi.__svalue, n171 block.call i.__svalue, n 168 172 end 169 173 end … … 210 214 # # => foo:2 211 215 # 212 def with_object(object )213 return to_enum(:with_object, object) unless block _given?216 def with_object(object, &block) 217 return to_enum(:with_object, object) unless block 214 218 215 219 enumerator_block_call do |i| 216 yield[i,object]220 block.call [i,object] 217 221 end 218 222 object … … 220 224 221 225 def inspect 222 return "#<#{self.class}: uninitialized>" unless @obj223 224 226 if @args && @args.size > 0 225 227 args = @args.join(", ") 226 "#<#{self.class}: #{@obj }:#{@meth}(#{args})>"228 "#<#{self.class}: #{@obj.inspect}:#{@meth}(#{args})>" 227 229 else 228 "#<#{self.class}: #{@obj }:#{@meth}>"230 "#<#{self.class}: #{@obj.inspect}:#{@meth}>" 229 231 end 230 232 end … … 242 244 # === Examples 243 245 # 244 # "Hello, world!".scan(/\w+/) #=> ["Hello", "world"] 245 # "Hello, world!".to_enum(:scan, /\w+/).to_a #=> ["Hello", "world"] 246 # "Hello, world!".to_enum(:scan).each(/\w+/).to_a #=> ["Hello", "world"] 246 # Array.new(3) #=> [nil, nil, nil] 247 # Array.new(3) { |i| i } #=> [0, 1, 2] 248 # Array.to_enum(:new, 3).to_a #=> [0, 1, 2] 249 # Array.to_enum(:new).each(3).to_a #=> [0, 1, 2] 247 250 # 248 251 # obj = Object.new … … 278 281 obj.args = args 279 282 end 280 return obj unless block _given?283 return obj unless block 281 284 enumerator_block_call(&block) 282 285 end … … 539 542 class Yielder 540 543 def initialize(&block) 541 raise LocalJumpError, "no block given" unless block _given?544 raise LocalJumpError, "no block given" unless block 542 545 543 546 @proc = block … … 553 556 end 554 557 end 558 559 ## 560 # call-seq: 561 # Enumerator.produce(initial = nil) { |val| } -> enumerator 562 # 563 # Creates an infinite enumerator from any block, just called over and 564 # over. Result of the previous iteration is passed to the next one. 565 # If +initial+ is provided, it is passed to the first iteration, and 566 # becomes the first element of the enumerator; if it is not provided, 567 # first iteration receives +nil+, and its result becomes first 568 # element of the iterator. 569 # 570 # Raising StopIteration from the block stops an iteration. 571 # 572 # Examples of usage: 573 # 574 # Enumerator.produce(1, &:succ) # => enumerator of 1, 2, 3, 4, .... 575 # 576 # Enumerator.produce { rand(10) } # => infinite random number sequence 577 # 578 # ancestors = Enumerator.produce(node) { |prev| node = prev.parent or raise StopIteration } 579 # enclosing_section = ancestors.find { |n| n.type == :section } 580 def Enumerator.produce(init=NONE, &block) 581 raise ArgumentError, "no block given" if block.nil? 582 Enumerator.new do |y| 583 if init == NONE 584 val = nil 585 else 586 val = init 587 y.yield(val) 588 end 589 begin 590 while true 591 y.yield(val = block.call(val)) 592 end 593 rescue StopIteration 594 # do nothing 595 end 596 end 597 end 555 598 end 556 599 … … 560 603 # obj.to_enum(method = :each, *args) -> enum 561 604 # obj.enum_for(method = :each, *args) -> enum 562 # obj.to_enum(method = :each, *args) {|*args| block} -> enum563 # obj.enum_for(method = :each, *args){|*args| block} -> enum564 605 # 565 606 # Creates a new Enumerator which will enumerate by calling +method+ on 566 607 # +obj+, passing +args+ if any. 567 #568 # If a block is given, it will be used to calculate the size of569 # the enumerator without the need to iterate it (see Enumerator#size).570 608 # 571 609 # === Examples … … 586 624 # a generic Enumerable, in case no block is passed. 587 625 # 588 # Here is such an example , with parameter passing and a sizing block:626 # Here is such an example with parameter passing: 589 627 # 590 628 # module Enumerable … … 593 631 # raise ArgumentError, "#{n} is negative!" if n < 0 594 632 # unless block_given? 595 # return to_enum(__method__, n) do # __method__ is :repeat here 596 # sz = size # Call size and multiply by n... 597 # sz * n if sz # but return nil if size itself is nil 598 # end 633 # return to_enum(__method__, n) # __method__ is :repeat here 599 634 # end 600 635 # each do |*val| … … 613 648 Enumerator.new self, meth, *args 614 649 end 615 alias :enum_for :to_enum650 alias enum_for to_enum 616 651 end 617 652 618 653 module Enumerable 619 654 # use Enumerator to use infinite sequence 620 def zip(*arg) 621 ary = [] 622 arg = arg.map{|a|a.each} 623 i = 0 624 self.each do |*val| 625 a = [] 626 a.push(val.__svalue) 627 idx = 0 628 while idx < arg.size 629 begin 630 a.push(arg[idx].next) 631 rescue StopIteration 632 a.push(nil) 655 def zip(*args, &block) 656 args = args.map do |a| 657 if a.respond_to?(:each) 658 a.to_enum(:each) 659 else 660 raise TypeError, "wrong argument type #{a.class} (must respond to :each)" 661 end 662 end 663 664 result = block ? nil : [] 665 666 each do |*val| 667 tmp = [val.__svalue] 668 args.each do |arg| 669 v = if arg.nil? 670 nil 671 else 672 begin 673 arg.next 674 rescue StopIteration 675 nil 676 end 633 677 end 634 idx += 1678 tmp.push(v) 635 679 end 636 ary.push(a) 637 i += 1 638 end 639 ary 680 if result.nil? 681 block.call(tmp) 682 else 683 result.push(tmp) 684 end 685 end 686 687 result 640 688 end 641 689 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-enumerator/test/enumerator.rb
r331 r439 7 7 end 8 8 9 assert 'Enumerator' do 9 def assert_take(exp, enumerator) 10 result = [] 11 n = exp.size 12 enumerator.each do |v| 13 result << v 14 n -= 1 15 break if n == 0 16 end if n > 0 17 assert_equal exp, result 18 end 19 20 assert 'Enumerator.class' do 10 21 assert_equal Class, Enumerator.class 11 22 end 12 23 13 assert 'Enumerator ' do24 assert 'Enumerator.superclass' do 14 25 assert_equal Object, Enumerator.superclass 15 26 end … … 20 31 assert_equal [[:x,1],[:y,2]], {x:1, y:2}.each.map{|i| i}.sort 21 32 assert_equal [1,2,3], @obj.to_enum(:foo, 1,2,3).to_a 22 assert_equal [1,2,3], Enumerator.new(@obj, :foo, 1,2,3).to_a 23 assert_equal [1,2,3], Enumerator.new { |y| i = 0; loop { y << (i += 1) } }.take(3) 33 assert_take [1,2,3], Enumerator.new { |y| i = 0; loop { y << (i += 1) } } 24 34 assert_raise(ArgumentError) { Enumerator.new } 25 enum = @obj.to_enum26 assert_raise(NoMethodError) { enum.each {} }27 35 28 36 # examples … … 34 42 end 35 43 end 36 assert_ equal fib.take(10), [1,1,2,3,5,8,13,21,34,55]44 assert_take [1,1,2,3,5,8,13,21,34,55], fib 37 45 end 38 46 … … 54 62 @obj.to_enum(:foo, 1, 2, 3).with_index(10).with_index(20) { |*i| a << i } 55 63 assert_equal [[[1, 10], 20], [[2, 11], 21], [[3, 12], 22]], a 56 end57 58 assert 'Enumerator#with_index nonnum offset' do59 s = Object.new60 def s.to_int; 1 end61 assert_equal([[1,1],[2,2],[3,3]], @obj.to_enum(:foo, 1, 2, 3).with_index(s).to_a)62 64 end 63 65 … … 100 102 assert 'Enumerator#inspect' do 101 103 e = (0..10).each 102 assert_equal("#<Enumerator: 0..10:each>", e.inspect) 103 e = Enumerator.new("FooObject", :foo, 1) 104 assert_equal("#<Enumerator: FooObject:foo(1)>", e.inspect) 105 e = Enumerator.new("FooObject", :foo, 1, 2, 3) 106 assert_equal("#<Enumerator: FooObject:foo(1, 2, 3)>", e.inspect) 104 assert_equal('#<Enumerator: 0..10:each>', e.inspect) 105 e = 'FooObject'.enum_for(:foo, 1) 106 assert_equal('#<Enumerator: "FooObject":foo(1)>', e.inspect) 107 e = 'FooObject'.enum_for(:foo, 1, 2, 3) 108 assert_equal('#<Enumerator: "FooObject":foo(1, 2, 3)>', e.inspect) 109 e = nil.enum_for(:to_s) 110 assert_equal('#<Enumerator: nil:to_s>', e.inspect) 107 111 end 108 112 … … 426 430 427 431 assert 'Kernel#to_enum' do 432 e = nil 428 433 assert_equal Enumerator, [].to_enum.class 429 assert_raise(ArgumentError){ nil.to_enum } 434 assert_nothing_raised { e = [].to_enum(:_not_implemented_) } 435 assert_raise(NoMethodError) { e.first } 430 436 end 431 437 … … 510 516 assert 'Hash#select' do 511 517 h = {1=>2,3=>4,5=>6} 512 hret = h.select.with_index {|a, b| a[1] == 4}518 hret = h.select.with_index {|a,_b| a[1] == 4} 513 519 assert_equal({3=>4}, hret) 514 520 assert_equal({1=>2,3=>4,5=>6}, h) … … 517 523 assert 'Hash#select!' do 518 524 h = {1=>2,3=>4,5=>6} 519 hret = h.select!.with_index {|a, b| a[1] == 4}525 hret = h.select!.with_index {|a,_b| a[1] == 4} 520 526 assert_equal h, hret 521 527 assert_equal({3=>4}, h) … … 524 530 assert 'Hash#reject' do 525 531 h = {1=>2,3=>4,5=>6} 526 hret = h.reject.with_index {|a, b| a[1] == 4}532 hret = h.reject.with_index {|a,_b| a[1] == 4} 527 533 assert_equal({1=>2,5=>6}, hret) 528 534 assert_equal({1=>2,3=>4,5=>6}, h) … … 531 537 assert 'Hash#reject!' do 532 538 h = {1=>2,3=>4,5=>6} 533 hret = h.reject!.with_index {|a, b| a[1] == 4}539 hret = h.reject!.with_index {|a,_b| a[1] == 4} 534 540 assert_equal h, hret 535 541 assert_equal({1=>2,5=>6}, h) … … 545 551 assert_equal [1,2,3,4,5], c 546 552 end 553 554 assert 'Enumerable#zip' do 555 assert_equal [[1, 10], [2, 11], [3, 12]], [1,2,3].zip(10..Float::INFINITY) 556 557 ret = [] 558 assert_equal nil, [1,2,3].zip(10..Float::INFINITY) { |i| ret << i } 559 assert_equal [[1, 10], [2, 11], [3, 12]], ret 560 561 assert_raise(TypeError) { [1].zip(1) } 562 end 563 564 assert 'Enumerator.produce' do 565 assert_raise(ArgumentError) { Enumerator.produce } 566 567 # Without initial object 568 passed_args = [] 569 enum = Enumerator.produce {|obj| passed_args << obj; (obj || 0).succ } 570 assert_equal Enumerator, enum.class 571 assert_take [1, 2, 3], enum 572 assert_equal [nil, 1, 2], passed_args 573 574 # With initial object 575 passed_args = [] 576 enum = Enumerator.produce(1) {|obj| passed_args << obj; obj.succ } 577 assert_take [1, 2, 3], enum 578 assert_equal [1, 2], passed_args 579 580 # Raising StopIteration 581 words = %w[The quick brown fox jumps over the lazy dog] 582 enum = Enumerator.produce { words.shift or raise StopIteration } 583 assert_equal %w[The quick brown fox jumps over the lazy dog], enum.to_a 584 585 # Raising StopIteration 586 object = [[[["abc", "def"], "ghi", "jkl"], "mno", "pqr"], "stuv", "wxyz"] 587 enum = Enumerator.produce(object) {|obj| 588 obj.respond_to?(:first) or raise StopIteration 589 obj.first 590 } 591 assert_nothing_raised { 592 assert_equal [ 593 [[[["abc", "def"], "ghi", "jkl"], "mno", "pqr"], "stuv", "wxyz"], 594 [[["abc", "def"], "ghi", "jkl"], "mno", "pqr"], 595 [["abc", "def"], "ghi", "jkl"], 596 ["abc", "def"], 597 "abc", 598 ], enum.to_a 599 } 600 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-error/src/exception.c
r331 r439 9 9 struct mrb_jmpbuf c_jmp; 10 10 mrb_value result = mrb_nil_value(); 11 int ai = mrb_gc_arena_save(mrb); 11 12 12 13 if (state) { *state = FALSE; } … … 23 24 } MRB_END_EXC(&c_jmp); 24 25 26 mrb_gc_arena_restore(mrb, ai); 25 27 mrb_gc_protect(mrb, result); 26 28 return result; … … 33 35 struct mrb_jmpbuf c_jmp; 34 36 mrb_value result; 37 int ai = mrb_gc_arena_save(mrb); 35 38 36 39 MRB_TRY(&c_jmp) { … … 40 43 } MRB_CATCH(&c_jmp) { 41 44 mrb->jmp = prev_jmp; 45 mrb_gc_arena_restore(mrb, ai); 42 46 ensure(mrb, e_data); 43 47 MRB_THROW(mrb->jmp); /* rethrow catched exceptions */ 44 48 } MRB_END_EXC(&c_jmp); 45 49 50 mrb_gc_arena_restore(mrb, ai); 51 mrb_gc_protect(mrb, result); 46 52 ensure(mrb, e_data); 53 mrb_gc_arena_restore(mrb, ai); 47 54 mrb_gc_protect(mrb, result); 48 55 return result; … … 65 72 mrb_bool error_matched = FALSE; 66 73 mrb_int i; 74 int ai = mrb_gc_arena_save(mrb); 67 75 68 76 MRB_TRY(&c_jmp) { … … 83 91 84 92 mrb->exc = NULL; 93 mrb_gc_arena_restore(mrb, ai); 85 94 result = rescue(mrb, r_data); 86 95 } MRB_END_EXC(&c_jmp); 87 96 97 mrb_gc_arena_restore(mrb, ai); 88 98 mrb_gc_protect(mrb, result); 89 99 return result; -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-eval/src/eval.c
r331 r439 13 13 get_closure_irep(mrb_state *mrb, int level) 14 14 { 15 struct mrb_context *c = mrb->c; 16 struct REnv *e = c->ci[-1].proc->env; 17 struct RProc *proc; 18 19 if (level == 0) { 20 proc = c->ci[-1].proc; 21 if (MRB_PROC_CFUNC_P(proc)) { 22 return NULL; 23 } 24 return proc->body.irep; 25 } 26 27 while (--level) { 28 e = (struct REnv*)e->c; 29 if (!e) return NULL; 30 } 31 32 if (!e) return NULL; 33 if (!MRB_ENV_STACK_SHARED_P(e)) return NULL; 34 c = e->cxt.c; 35 proc = c->cibase[e->cioff].proc; 36 37 if (!proc || MRB_PROC_CFUNC_P(proc)) { 15 struct RProc *proc = mrb->c->ci[-1].proc; 16 17 while (level--) { 18 if (!proc) return NULL; 19 proc = proc->upper; 20 } 21 if (!proc) return NULL; 22 if (MRB_PROC_CFUNC_P(proc)) { 38 23 return NULL; 39 24 } … … 41 26 } 42 27 43 static inline mrb_code 28 /* search for irep lev above the bottom */ 29 static mrb_irep* 30 search_irep(mrb_irep *top, int bnest, int lev, mrb_irep *bottom) 31 { 32 int i; 33 34 for (i=0; i<top->rlen; i++) { 35 mrb_irep* tmp = top->reps[i]; 36 37 if (tmp == bottom) return top; 38 tmp = search_irep(tmp, bnest-1, lev, bottom); 39 if (tmp) { 40 if (bnest == lev) return top; 41 return tmp; 42 } 43 } 44 return NULL; 45 } 46 47 static uint16_t 44 48 search_variable(mrb_state *mrb, mrb_sym vsym, int bnest) 45 49 { … … 49 53 50 54 for (level = 0; (virep = get_closure_irep(mrb, level)); level++) { 51 if ( !virep ||virep->lv == NULL) {55 if (virep->lv == NULL) { 52 56 continue; 53 57 } 54 58 for (pos = 0; pos < virep->nlocals - 1; pos++) { 55 59 if (vsym == virep->lv[pos].name) { 56 return (MKARG_B(pos + 1) | MKARG_C(level + bnest)); 57 } 58 } 59 } 60 60 return (pos+1)<<8 | (level+bnest); 61 } 62 } 63 } 64 65 return 0; 66 } 67 68 static int 69 irep_argc(mrb_irep *irep) 70 { 71 mrb_code c; 72 73 c = irep->iseq[0]; 74 if (c == OP_ENTER) { 75 mrb_aspec ax = PEEK_W(irep->iseq+1); 76 /* extra 1 means a slot for block */ 77 return MRB_ASPEC_REQ(ax)+MRB_ASPEC_OPT(ax)+MRB_ASPEC_REST(ax)+MRB_ASPEC_POST(ax)+1; 78 } 61 79 return 0; 62 80 } … … 71 89 } 72 90 91 extern uint8_t mrb_insn_size[]; 92 extern uint8_t mrb_insn_size1[]; 93 extern uint8_t mrb_insn_size2[]; 94 extern uint8_t mrb_insn_size3[]; 95 73 96 static void 74 patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest) 75 { 76 size_t i; 77 mrb_code c; 78 int argc = 0; 79 80 for (i = 0; i < irep->ilen; i++) { 81 c = irep->iseq[i]; 82 switch(GET_OPCODE(c)){ 83 case OP_ENTER: 84 { 85 mrb_aspec ax = GETARG_Ax(c); 86 /* extra 1 means a slot for block */ 87 argc = MRB_ASPEC_REQ(ax)+MRB_ASPEC_OPT(ax)+MRB_ASPEC_REST(ax)+MRB_ASPEC_POST(ax)+1; 88 } 89 break; 90 97 patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest, mrb_irep *top) 98 { 99 int i; 100 uint32_t a; 101 uint16_t b; 102 uint8_t c; 103 mrb_code insn; 104 int argc = irep_argc(irep); 105 mrb_code *iseq = (mrb_code *)irep->iseq; 106 107 mrb_assert((irep->flags & MRB_ISEQ_NO_FREE) == 0); 108 109 for (i = 0; i < irep->ilen; ) { 110 insn = iseq[i]; 111 switch(insn){ 91 112 case OP_EPUSH: 92 patch_irep(mrb, irep->reps[GETARG_Bx(c)], bnest + 1); 113 a = PEEK_B(iseq+i+1); 114 patch_irep(mrb, irep->reps[a], bnest + 1, top); 93 115 break; 94 116 95 117 case OP_LAMBDA: 96 { 97 int arg_c = GETARG_c(c); 98 if (arg_c & OP_L_CAPTURE) { 99 patch_irep(mrb, irep->reps[GETARG_b(c)], bnest + 1); 100 } 101 } 118 case OP_BLOCK: 119 a = PEEK_B(iseq+i+1); 120 b = PEEK_B(iseq+i+2); 121 patch_irep(mrb, irep->reps[b], bnest + 1, top); 102 122 break; 103 123 104 124 case OP_SEND: 105 if (GETARG_C(c) != 0) { 125 b = PEEK_B(iseq+i+2); 126 c = PEEK_B(iseq+i+3); 127 if (c != 0) { 106 128 break; 107 129 } 108 {109 mrb_code arg = search_variable(mrb, irep->syms[GETARG_B(c)], bnest);130 else { 131 uint16_t arg = search_variable(mrb, irep->syms[b], bnest); 110 132 if (arg != 0) { 111 133 /* must replace */ 112 irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg; 134 iseq[i] = OP_GETUPVAR; 135 iseq[i+2] = arg >> 8; 136 iseq[i+3] = arg & 0xff; 113 137 } 114 138 } … … 116 140 117 141 case OP_MOVE: 142 a = PEEK_B(iseq+i+1); 143 b = PEEK_B(iseq+i+2); 118 144 /* src part */ 119 if (potential_upvar_p(irep->lv, GETARG_B(c), argc, irep->nlocals)) {120 mrb_code arg = search_variable(mrb, irep->lv[GETARG_B(c)- 1].name, bnest);145 if (potential_upvar_p(irep->lv, b, argc, irep->nlocals)) { 146 uint16_t arg = search_variable(mrb, irep->lv[b - 1].name, bnest); 121 147 if (arg != 0) { 122 148 /* must replace */ 123 irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg; 149 iseq[i] = insn = OP_GETUPVAR; 150 iseq[i+2] = arg >> 8; 151 iseq[i+3] = arg & 0xff; 124 152 } 125 153 } 126 154 /* dst part */ 127 if (potential_upvar_p(irep->lv, GETARG_A(c), argc, irep->nlocals)) {128 mrb_code arg = search_variable(mrb, irep->lv[GETARG_A(c)- 1].name, bnest);155 if (potential_upvar_p(irep->lv, a, argc, irep->nlocals)) { 156 uint16_t arg = search_variable(mrb, irep->lv[a - 1].name, bnest); 129 157 if (arg != 0) { 130 158 /* must replace */ 131 irep->iseq[i] = MKOPCODE(OP_SETUPVAR) | MKARG_A(GETARG_B(c)) | arg; 132 } 133 } 134 break; 135 136 case OP_STOP: 137 if (mrb->c->ci->acc >= 0) { 138 irep->iseq[i] = MKOP_AB(OP_RETURN, irep->nlocals, OP_R_NORMAL); 139 } 140 break; 141 } 159 iseq[i] = insn = OP_SETUPVAR; 160 iseq[i+1] = (mrb_code)b; 161 iseq[i+2] = arg >> 8; 162 iseq[i+3] = arg & 0xff; 163 } 164 } 165 break; 166 167 case OP_GETUPVAR: 168 a = PEEK_B(iseq+i+1); 169 b = PEEK_B(iseq+i+2); 170 c = PEEK_B(iseq+i+3); 171 { 172 int lev = c+1; 173 mrb_irep *tmp = search_irep(top, bnest, lev, irep); 174 if (potential_upvar_p(tmp->lv, b, irep_argc(tmp), tmp->nlocals)) { 175 uint16_t arg = search_variable(mrb, tmp->lv[b-1].name, bnest); 176 if (arg != 0) { 177 /* must replace */ 178 iseq[i] = OP_GETUPVAR; 179 iseq[i+2] = arg >> 8; 180 iseq[i+3] = arg & 0xff; 181 } 182 } 183 } 184 break; 185 186 case OP_SETUPVAR: 187 a = PEEK_B(iseq+i+1); 188 b = PEEK_B(iseq+i+2); 189 c = PEEK_B(iseq+i+3); 190 { 191 int lev = c+1; 192 mrb_irep *tmp = search_irep(top, bnest, lev, irep); 193 if (potential_upvar_p(tmp->lv, b, irep_argc(tmp), tmp->nlocals)) { 194 uint16_t arg = search_variable(mrb, tmp->lv[b-1].name, bnest); 195 if (arg != 0) { 196 /* must replace */ 197 iseq[i] = OP_SETUPVAR; 198 iseq[i+1] = a; 199 iseq[i+2] = arg >> 8; 200 iseq[i+3] = arg & 0xff; 201 } 202 } 203 } 204 break; 205 206 case OP_EXT1: 207 insn = PEEK_B(iseq+i+1); 208 i += mrb_insn_size1[insn]+1; 209 continue; 210 case OP_EXT2: 211 insn = PEEK_B(iseq+i+1); 212 i += mrb_insn_size2[insn]+1; 213 continue; 214 case OP_EXT3: 215 insn = PEEK_B(iseq+i+1); 216 i += mrb_insn_size3[insn]+1; 217 continue; 218 } 219 i+=mrb_insn_size[insn]; 142 220 } 143 221 } … … 146 224 147 225 static struct RProc* 148 create_proc_from_string(mrb_state *mrb, char *s, int len, mrb_value binding, const char *file, mrb_int line)226 create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding, const char *file, mrb_int line) 149 227 { 150 228 mrbc_context *cxt; … … 152 230 struct RProc *proc; 153 231 struct REnv *e; 154 struct mrb_context *c = mrb->c; 232 mrb_callinfo *ci; /* callinfo of eval caller */ 233 struct RClass *target_class = NULL; 234 int bidx; 155 235 156 236 if (!mrb_nil_p(binding)) { … … 159 239 160 240 cxt = mrbc_context_new(mrb); 161 cxt->lineno = line;241 cxt->lineno = (uint16_t)line; 162 242 163 243 mrbc_filename(mrb, cxt, file ? file : "(eval)"); 164 244 cxt->capture_errors = TRUE; 165 245 cxt->no_optimize = TRUE; 246 cxt->on_eval = TRUE; 166 247 167 248 p = mrb_parse_nstring(mrb, s, len, cxt); … … 177 258 178 259 if (file) { 179 str = mrb_format(mrb, " file %S line %S: %S",180 mrb_str_new_cstr(mrb, file),181 mrb_fixnum_value(p->error_buffer[0].lineno),182 mrb_str_new_cstr(mrb, p->error_buffer[0].message));260 str = mrb_format(mrb, "file %s line %d: %s", 261 file, 262 p->error_buffer[0].lineno, 263 p->error_buffer[0].message); 183 264 } 184 265 else { 185 str = mrb_format(mrb, " line %S: %S",186 mrb_fixnum_value(p->error_buffer[0].lineno),187 mrb_str_new_cstr(mrb, p->error_buffer[0].message));266 str = mrb_format(mrb, "line %d: %s", 267 p->error_buffer[0].lineno, 268 p->error_buffer[0].message); 188 269 } 189 270 mrb_parser_free(p); … … 199 280 mrb_raise(mrb, E_SCRIPT_ERROR, "codegen error"); 200 281 } 201 if (c->ci[-1].proc->target_class) { 202 proc->target_class = c->ci[-1].proc->target_class; 203 } 204 e = c->ci[-1].proc->env; 205 if (!e) e = c->ci[-1].env; 206 e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)e); 207 e->cxt.c = c; 208 e->cioff = c->ci - c->cibase; 209 e->stack = c->ci->stackent; 210 MRB_SET_ENV_STACK_LEN(e, c->ci->proc->body.irep->nlocals); 211 c->ci->target_class = proc->target_class; 212 c->ci->env = 0; 213 proc->env = e; 214 patch_irep(mrb, proc->body.irep, 0); 282 if (mrb->c->ci > mrb->c->cibase) { 283 ci = &mrb->c->ci[-1]; 284 } 285 else { 286 ci = mrb->c->cibase; 287 } 288 if (ci->proc) { 289 target_class = MRB_PROC_TARGET_CLASS(ci->proc); 290 } 291 if (ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) { 292 if (ci->env) { 293 e = ci->env; 294 } 295 else { 296 e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, 297 (struct RClass*)target_class); 298 e->mid = ci->mid; 299 e->stack = ci[1].stackent; 300 e->cxt = mrb->c; 301 MRB_ENV_SET_STACK_LEN(e, ci->proc->body.irep->nlocals); 302 bidx = ci->argc; 303 if (ci->argc < 0) bidx = 2; 304 else bidx += 1; 305 MRB_ENV_SET_BIDX(e, bidx); 306 ci->env = e; 307 } 308 proc->e.env = e; 309 proc->flags |= MRB_PROC_ENVSET; 310 mrb_field_write_barrier(mrb, (struct RBasic*)proc, (struct RBasic*)e); 311 } 312 proc->upper = ci->proc; 313 mrb->c->ci->target_class = target_class; 314 patch_irep(mrb, proc->body.irep, 0, proc->body.irep); 315 /* mrb_codedump_all(mrb, proc); */ 215 316 216 317 mrb_parser_free(p); … … 223 324 exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc) 224 325 { 326 /* no argument passed from eval() */ 327 mrb->c->ci->argc = 0; 225 328 if (mrb->c->ci->acc < 0) { 226 mrb_value ret = mrb_top_run(mrb, proc, mrb->c->stack[0], 0); 329 ptrdiff_t cioff = mrb->c->ci - mrb->c->cibase; 330 mrb_value ret = mrb_top_run(mrb, proc, self, 0); 227 331 if (mrb->exc) { 228 332 mrb_exc_raise(mrb, mrb_obj_value(mrb->exc)); 229 333 } 334 mrb->c->ci = mrb->c->cibase + cioff; 230 335 return ret; 231 336 } 337 /* clear block */ 338 mrb->c->stack[1] = mrb_nil_value(); 232 339 return mrb_exec_irep(mrb, self, proc); 233 340 } … … 256 363 mrb_int argc; mrb_value *argv; 257 364 258 mrb_get_args(mrb, "* &", &argv, &argc, &b);365 mrb_get_args(mrb, "*!&", &argv, &argc, &b); 259 366 260 367 if (mrb_nil_p(b)) { … … 269 376 cv = mrb_singleton_class(mrb, self); 270 377 proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line); 271 proc->target_class = mrb_class_ptr(cv); 272 mrb->c->ci->env = NULL; 378 MRB_PROC_SET_TARGET_CLASS(proc, mrb_class_ptr(cv)); 273 379 mrb_assert(!MRB_PROC_CFUNC_P(proc)); 380 mrb->c->ci->target_class = mrb_class_ptr(cv); 274 381 return exec_irep(mrb, self, proc); 275 382 } … … 284 391 { 285 392 mrb_define_module_function(mrb, mrb->kernel_module, "eval", f_eval, MRB_ARGS_ARG(1, 3)); 286 mrb_define_method(mrb, mrb ->kernel_module, "instance_eval", f_instance_eval, MRB_ARGS_ARG(1, 2));393 mrb_define_method(mrb, mrb_class_get(mrb, "BasicObject"), "instance_eval", f_instance_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK()); 287 394 } 288 395 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-eval/test/eval.rb
r331 r439 35 35 assert_equal(2) { 36 36 a = 10 37 Kernel.eval 'def f(a); b=a .send(:+, 1); end'37 Kernel.eval 'def f(a); b=a+1; end' 38 38 f(1) 39 39 } … … 59 59 assert('String instance_eval') do 60 60 obj = Object.new 61 obj.instance_ variable_set :@test, 'test'61 obj.instance_eval{ @test = 'test' } 62 62 assert_raise(ArgumentError) { obj.instance_eval(0) { } } 63 63 assert_raise(ArgumentError) { obj.instance_eval('0', 'test', 0, 'test') } … … 81 81 end 82 82 83 assert(' Object#instance_eval with begin-rescue-ensure execution order') do83 assert('BasicObject#instance_eval with begin-rescue-ensure execution order') do 84 84 class HellRaiser 85 85 def raise_hell … … 100 100 assert_equal([:enter_raise_hell, :begin, :rescue, :ensure], hell_raiser.raise_hell) 101 101 end 102 103 assert('BasicObject#instance_eval to define singleton methods Issue #3141') do 104 foo_class = Class.new do 105 def bar(x) 106 instance_eval "def baz; #{x}; end" 107 end 108 end 109 110 f1 = foo_class.new 111 f2 = foo_class.new 112 f1.bar 1 113 f2.bar 2 114 assert_equal(1){f1.baz} 115 assert_equal(2){f2.baz} 116 end 117 118 assert('Kernel.#eval(string) Issue #4021') do 119 assert_equal('FOO') { (eval <<'EOS').call } 120 foo = "FOO" 121 Proc.new { foo } 122 EOS 123 assert_equal('FOO') { 124 def do_eval(code) 125 eval(code) 126 end 127 do_eval(<<'EOS').call 128 foo = "FOO" 129 Proc.new { foo } 130 EOS 131 } 132 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-exit/src/mruby-exit.c
r331 r439 5 5 f_exit(mrb_state *mrb, mrb_value self) 6 6 { 7 mrb_int i = EXIT_SUCCESS; 7 mrb_value status = mrb_true_value(); 8 int istatus; 8 9 9 mrb_get_args(mrb, "|i", &i); 10 exit(i); 10 mrb_get_args(mrb, "|o", &status); 11 istatus = mrb_true_p(status) ? EXIT_SUCCESS : 12 mrb_false_p(status) ? EXIT_FAILURE : 13 (int)mrb_int(mrb, status); 14 exit(istatus); 15 11 16 /* not reached */ 12 return mrb_nil_value();17 return status; 13 18 } 14 19 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-fiber/src/fiber.c
r331 r439 73 73 size_t slen; 74 74 75 mrb_get_args(mrb, "& ", &blk);75 mrb_get_args(mrb, "&!", &blk); 76 76 77 77 if (f->cxt) { 78 78 mrb_raise(mrb, E_RUNTIME_ERROR, "cannot initialize twice"); 79 }80 if (mrb_nil_p(blk)) {81 mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Fiber object without a block");82 79 } 83 80 p = mrb_proc_ptr(blk); … … 124 121 /* adjust return callinfo */ 125 122 ci = c->ci; 126 ci->target_class = p->target_class;123 ci->target_class = MRB_PROC_TARGET_CLASS(p); 127 124 ci->proc = p; 125 mrb_field_write_barrier(mrb, (struct RBasic*)mrb_obj_ptr(self), (struct RBasic*)p); 128 126 ci->pc = p->body.irep->iseq; 129 ci->nregs = p->body.irep->nregs;130 127 ci[1] = ci[0]; 131 128 c->ci++; /* push dummy callinfo */ … … 187 184 struct mrb_context *c = fiber_check(mrb, self); 188 185 struct mrb_context *old_c = mrb->c; 186 enum mrb_fiber_state status; 189 187 mrb_value value; 190 188 191 189 fiber_check_cfunc(mrb, c); 192 if (resume && c->status == MRB_FIBER_TRANSFERRED) { 193 mrb_raise(mrb, E_FIBER_ERROR, "resuming transferred fiber"); 194 } 195 if (c->status == MRB_FIBER_RUNNING || c->status == MRB_FIBER_RESUMED) { 196 mrb_raise(mrb, E_FIBER_ERROR, "double resume (fib)"); 197 } 198 if (c->status == MRB_FIBER_TERMINATED) { 190 status = c->status; 191 switch (status) { 192 case MRB_FIBER_TRANSFERRED: 193 if (resume) { 194 mrb_raise(mrb, E_FIBER_ERROR, "resuming transferred fiber"); 195 } 196 break; 197 case MRB_FIBER_RUNNING: 198 case MRB_FIBER_RESUMED: 199 mrb_raise(mrb, E_FIBER_ERROR, "double resume"); 200 break; 201 case MRB_FIBER_TERMINATED: 199 202 mrb_raise(mrb, E_FIBER_ERROR, "resuming dead fiber"); 200 } 201 mrb->c->status = resume ? MRB_FIBER_RESUMED : MRB_FIBER_TRANSFERRED; 203 break; 204 default: 205 break; 206 } 207 old_c->status = resume ? MRB_FIBER_RESUMED : MRB_FIBER_TRANSFERRED; 202 208 c->prev = resume ? mrb->c : (c->prev ? c->prev : mrb->root_c); 203 if (c->status == MRB_FIBER_CREATED) { 209 fiber_switch_context(mrb, c); 210 if (status == MRB_FIBER_CREATED) { 204 211 mrb_value *b, *e; 205 212 206 if ( len >= c->stend - c->stack) {207 mrb_raise(mrb, E_FIBER_ERROR, " too many arguments to fiber");213 if (!c->ci->proc) { 214 mrb_raise(mrb, E_FIBER_ERROR, "double resume (current)"); 208 215 } 216 mrb_stack_extend(mrb, len+2); /* for receiver and (optional) block */ 209 217 b = c->stack+1; 210 218 e = b + len; … … 212 220 *b++ = *a++; 213 221 } 214 c->cibase->argc = len;215 value = c->stack[0] = c->ci->proc->env->stack[0];222 c->cibase->argc = (int)len; 223 value = c->stack[0] = MRB_PROC_ENV(c->ci->proc)->stack[0]; 216 224 } 217 225 else { 218 226 value = fiber_result(mrb, a, len); 219 227 } 220 fiber_switch_context(mrb, c);221 228 222 229 if (vmexec) { … … 253 260 mrb_bool vmexec = FALSE; 254 261 255 mrb_get_args(mrb, "* ", &a, &len);262 mrb_get_args(mrb, "*!", &a, &len); 256 263 if (mrb->c->ci->acc < 0) { 257 264 vmexec = TRUE; … … 274 281 * execution of the fiber block this method will always return false. 275 282 */ 276 staticmrb_value277 fiber_alive_p(mrb_state *mrb, mrb_value self)283 MRB_API mrb_value 284 mrb_fiber_alive_p(mrb_state *mrb, mrb_value self) 278 285 { 279 286 struct mrb_context *c = fiber_check(mrb, self); 280 287 return mrb_bool_value(c->status != MRB_FIBER_TERMINATED); 281 288 } 289 #define fiber_alive_p mrb_fiber_alive_p 282 290 283 291 static mrb_value … … 287 295 mrb_get_args(mrb, "o", &other); 288 296 289 if ( mrb_type(other) != MRB_TT_FIBER) {297 if (!mrb_fiber_p(other)) { 290 298 return mrb_false_value(); 291 299 } … … 313 321 314 322 fiber_check_cfunc(mrb, mrb->c); 315 mrb_get_args(mrb, "* ", &a, &len);323 mrb_get_args(mrb, "*!", &a, &len); 316 324 317 325 if (c == mrb->root_c) { … … 371 379 mrb_int len; 372 380 373 mrb_get_args(mrb, "* ", &a, &len);381 mrb_get_args(mrb, "*!", &a, &len); 374 382 return mrb_fiber_yield(mrb, len, a); 375 383 } … … 402 410 MRB_SET_INSTANCE_TT(c, MRB_TT_FIBER); 403 411 404 mrb_define_method(mrb, c, "initialize", fiber_init, MRB_ARGS_NONE() );412 mrb_define_method(mrb, c, "initialize", fiber_init, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); 405 413 mrb_define_method(mrb, c, "resume", fiber_resume, MRB_ARGS_ANY()); 406 414 mrb_define_method(mrb, c, "transfer", fiber_transfer, MRB_ARGS_ANY()); -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-fiber/test/fiber.rb
r321 r439 77 77 78 78 assert('Fiber with splat in the block argument list') { 79 Fiber.new{|*x|x}.resume(1) == [1]79 assert_equal([1], Fiber.new{|*x|x}.resume(1)) 80 80 } 81 81 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-hash-ext/mrbgem.rake
r321 r439 3 3 spec.author = 'mruby developers' 4 4 spec.summary = 'Hash class extension' 5 spec.add_dependency 'mruby-enum-ext', :core => 'mruby-enum-ext' 6 spec.add_dependency 'mruby-array-ext', :core => 'mruby-array-ext' 5 spec.add_dependency 'mruby-array-ext', core: 'mruby-array-ext' 7 6 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-hash-ext/mrblib/hash.rb
r331 r439 28 28 if length == 1 29 29 o = object[0] 30 if o.respond_to?(:to_hash)30 if Hash === o 31 31 h = self.new 32 o bject[0].to_hash.each { |k, v| h[k] = v }32 o.each { |k, v| h[k] = v } 33 33 return h 34 34 elsif o.respond_to?(:to_a) … … 63 63 ## 64 64 # call-seq: 65 # Hash.try_convert(obj) -> hash or nil66 #67 # Try to convert <i>obj</i> into a hash, using to_hash method.68 # Returns converted hash or nil if <i>obj</i> cannot be converted69 # for any reason.70 #71 # Hash.try_convert({1=>2}) # => {1=>2}72 # Hash.try_convert("1=>2") # => nil73 #74 def self.try_convert(obj)75 if obj.respond_to?(:to_hash)76 obj.to_hash77 else78 nil79 end80 end81 82 ##83 # call-seq:84 65 # hsh.merge!(other_hash) -> hsh 85 66 # hsh.merge!(other_hash){|key, oldval, newval| block} -> hsh … … 102 83 103 84 def merge!(other, &block) 104 raise TypeError, " can't convert argument into Hash" unless other.respond_to?(:to_hash)85 raise TypeError, "Hash required (#{other.class} given)" unless Hash === other 105 86 if block 106 87 other.each_key{|k| … … 114 95 115 96 alias update merge! 97 98 ## 99 # call-seq: 100 # hsh.compact! -> hsh 101 # 102 # Removes all nil values from the hash. Returns the hash. 103 # Returns nil if the hash does not contain nil values. 104 # 105 # h = { a: 1, b: false, c: nil } 106 # h.compact! #=> { a: 1, b: false } 107 # 108 109 def compact! 110 keys = self.keys 111 nk = keys.select{|k| 112 self[k] != nil 113 } 114 return nil if (keys.size == nk.size) 115 h = {} 116 nk.each {|k| 117 h[k] = self[k] 118 } 119 h 120 self.replace(h) 121 end 122 123 ## 124 # call-seq: 125 # hsh.compact -> new_hsh 126 # 127 # Returns a new hash with the nil values/key pairs removed 128 # 129 # h = { a: 1, b: false, c: nil } 130 # h.compact #=> { a: 1, b: false } 131 # h #=> { a: 1, b: false, c: nil } 132 # 133 def compact 134 h = {} 135 self.keys.select{|k| 136 self[k] != nil 137 }.each {|k| 138 h[k] = self[k] 139 } 140 h 141 end 116 142 117 143 ## … … 150 176 none 151 177 else 152 raise KeyError, "Key not found: #{key }"178 raise KeyError, "Key not found: #{key.inspect}" 153 179 end 154 180 else … … 172 198 173 199 def delete_if(&block) 174 return to_enum :delete_if unless block _given?200 return to_enum :delete_if unless block 175 201 176 202 self.each do |k, v| … … 229 255 230 256 def keep_if(&block) 231 return to_enum :keep_if unless block _given?257 return to_enum :keep_if unless block 232 258 233 259 keys = [] … … 285 311 # 286 312 def <(hash) 287 begin 288 hash = hash.to_hash 289 rescue NoMethodError 290 raise TypeError, "can't convert #{hash.class} to Hash" 291 end 313 raise TypeError, "can't convert #{hash.class} to Hash" unless Hash === hash 292 314 size < hash.size and all? {|key, val| 293 315 hash.key?(key) and hash[key] == val … … 309 331 # 310 332 def <=(hash) 311 begin 312 hash = hash.to_hash 313 rescue NoMethodError 314 raise TypeError, "can't convert #{hash.class} to Hash" 315 end 333 raise TypeError, "can't convert #{hash.class} to Hash" unless Hash === hash 316 334 size <= hash.size and all? {|key, val| 317 335 hash.key?(key) and hash[key] == val … … 333 351 # 334 352 def >(hash) 335 begin 336 hash = hash.to_hash 337 rescue NoMethodError 338 raise TypeError, "can't convert #{hash.class} to Hash" 339 end 353 raise TypeError, "can't convert #{hash.class} to Hash" unless Hash === hash 340 354 size > hash.size and hash.all? {|key, val| 341 355 key?(key) and self[key] == val … … 357 371 # 358 372 def >=(hash) 359 begin 360 hash = hash.to_hash 361 rescue NoMethodError 362 raise TypeError, "can't convert #{hash.class} to Hash" 363 end 373 raise TypeError, "can't convert #{hash.class} to Hash" unless Hash === hash 364 374 size >= hash.size and hash.all? {|key, val| 365 375 key?(key) and self[key] == val … … 383 393 end 384 394 end 395 396 ## 397 # call-seq: 398 # hsh.transform_keys {|key| block } -> new_hash 399 # hsh.transform_keys -> an_enumerator 400 # 401 # Returns a new hash, with the keys computed from running the block 402 # once for each key in the hash, and the values unchanged. 403 # 404 # If no block is given, an enumerator is returned instead. 405 # 406 def transform_keys(&block) 407 return to_enum :transform_keys unless block 408 hash = {} 409 self.keys.each do |k| 410 new_key = block.call(k) 411 hash[new_key] = self[k] 412 end 413 hash 414 end 415 ## 416 # call-seq: 417 # hsh.transform_keys! {|key| block } -> hsh 418 # hsh.transform_keys! -> an_enumerator 419 # 420 # Invokes the given block once for each key in <i>hsh</i>, replacing it 421 # with the new key returned by the block, and then returns <i>hsh</i>. 422 # 423 # If no block is given, an enumerator is returned instead. 424 # 425 def transform_keys!(&block) 426 return to_enum :transform_keys! unless block 427 self.keys.each do |k| 428 value = self[k] 429 self.__delete(k) 430 k = block.call(k) if block 431 self[k] = value 432 end 433 self 434 end 435 ## 436 # call-seq: 437 # hsh.transform_values {|value| block } -> new_hash 438 # hsh.transform_values -> an_enumerator 439 # 440 # Returns a new hash with the results of running the block once for 441 # every value. 442 # This method does not change the keys. 443 # 444 # If no block is given, an enumerator is returned instead. 445 # 446 def transform_values(&b) 447 return to_enum :transform_values unless block_given? 448 hash = {} 449 self.keys.each do |k| 450 hash[k] = yield(self[k]) 451 end 452 hash 453 end 454 455 ## 456 # call-seq: 457 # hsh.transform_values! {|key| block } -> hsh 458 # hsh.transform_values! -> an_enumerator 459 # 460 # Invokes the given block once for each value in the hash, replacing 461 # with the new value returned by the block, and then returns <i>hsh</i>. 462 # 463 # If no block is given, an enumerator is returned instead. 464 # 465 def transform_values!(&b) 466 return to_enum :transform_values! unless block_given? 467 self.keys.each do |k| 468 self[k] = yield(self[k]) 469 end 470 self 471 end 472 473 def to_proc 474 ->x{self[x]} 475 end 476 477 ## 478 # call-seq: 479 # hsh.fetch_values(key, ...) -> array 480 # hsh.fetch_values(key, ...) { |key| block } -> array 481 # 482 # Returns an array containing the values associated with the given keys 483 # but also raises <code>KeyError</code> when one of keys can't be found. 484 # Also see <code>Hash#values_at</code> and <code>Hash#fetch</code>. 485 # 486 # h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" } 487 # 488 # h.fetch_values("cow", "cat") #=> ["bovine", "feline"] 489 # h.fetch_values("cow", "bird") # raises KeyError 490 # h.fetch_values("cow", "bird") { |k| k.upcase } #=> ["bovine", "BIRD"] 491 # 492 def fetch_values(*keys, &block) 493 keys.map do |k| 494 self.fetch(k, &block) 495 end 496 end 497 498 alias filter select 499 alias filter! select! 385 500 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-hash-ext/src/hash-ext.c
r331 r439 37 37 } 38 38 39 /* 40 * call-seq: 41 * hsh.slice(*keys) -> a_hash 42 * 43 * Returns a hash containing only the given keys and their values. 44 * 45 * h = { a: 100, b: 200, c: 300 } 46 * h.slice(:a) #=> {:a=>100} 47 * h.slice(:b, :c, :d) #=> {:b=>200, :c=>300} 48 */ 49 static mrb_value 50 hash_slice(mrb_state *mrb, mrb_value hash) 51 { 52 mrb_value *argv, result; 53 mrb_int argc, i; 54 55 mrb_get_args(mrb, "*", &argv, &argc); 56 result = mrb_hash_new_capa(mrb, argc); 57 if (argc == 0) return result; /* empty hash */ 58 for (i = 0; i < argc; i++) { 59 mrb_value key = argv[i]; 60 mrb_value val; 61 62 val = mrb_hash_fetch(mrb, hash, key, mrb_undef_value()); 63 if (!mrb_undef_p(val)) { 64 mrb_hash_set(mrb, result, key, val); 65 } 66 } 67 return result; 68 } 69 39 70 void 40 71 mrb_mruby_hash_ext_gem_init(mrb_state *mrb) … … 44 75 h = mrb->hash_class; 45 76 mrb_define_method(mrb, h, "values_at", hash_values_at, MRB_ARGS_ANY()); 77 mrb_define_method(mrb, h, "slice", hash_slice, MRB_ARGS_ANY()); 46 78 } 47 79 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-hash-ext/test/hash.rb
r331 r439 46 46 end 47 47 48 assert('Hash.try_convert') do49 assert_nil Hash.try_convert(nil)50 assert_nil Hash.try_convert("{1=>2}")51 assert_equal({1=>2}, Hash.try_convert({1=>2}))52 end53 54 48 assert('Hash#merge!') do 55 49 a = { 'abc_key' => 'abc_value', 'cba_key' => 'cba_value' } … … 81 75 h = Hash.new { |hash,k| hash[k] = k } 82 76 assert_equal keys, h.values_at(*keys) 77 end 78 79 assert('Hash#compact') do 80 h = { "cat" => "feline", "dog" => nil, "cow" => false } 81 82 assert_equal({ "cat" => "feline", "cow" => false }, h.compact) 83 assert_equal({ "cat" => "feline", "dog" => nil, "cow" => false }, h) 84 end 85 86 assert('Hash#compact!') do 87 h = { "cat" => "feline", "dog" => nil, "cow" => false } 88 89 h.compact! 90 assert_equal({ "cat" => "feline", "cow" => false }, h) 83 91 end 84 92 … … 255 263 assert_nil(h.dig(:d)) 256 264 end 265 266 assert("Hash#transform_keys") do 267 h = {"1" => 100, "2" => 200} 268 assert_equal({"1!" => 100, "2!" => 200}, 269 h.transform_keys{|k| k+"!"}) 270 assert_equal({1 => 100, 2 => 200}, 271 h.transform_keys{|k|k.to_i}) 272 assert_same(h, h.transform_keys!{|k|k.to_i}) 273 assert_equal({1 => 100, 2 => 200}, h) 274 end 275 276 assert("Hash#transform_values") do 277 h = {a: 1, b: 2, c: 3} 278 assert_equal({a: 2, b: 5, c: 10}, 279 h.transform_values{|v| v * v + 1}) 280 assert_equal({a: "1", b: "2", c: "3"}, 281 h.transform_values{|v|v.to_s}) 282 assert_same(h, h.transform_values!{|v|v.to_s}) 283 assert_equal({a: "1", b: "2", c: "3"}, h) 284 end 285 286 assert("Hash#slice") do 287 h = { a: 100, b: 200, c: 300 } 288 assert_equal({:a=>100}, h.slice(:a)) 289 assert_equal({:b=>200, :c=>300}, h.slice(:b, :c, :d)) 290 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-inline-struct/test/inline.c
r331 r439 12 12 mrb_get_args(mrb, "o", &object); 13 13 14 if (mrb_float_p(object)) 15 { 16 snprintf(string, size, "float(%.3f)", mrb_float(object)); 14 if (mrb_fixnum_p(object)) { 15 strncpy(string, "fixnum", size-1); 17 16 } 18 else if (mrb_fixnum_p(object)) 19 {20 s nprintf(string, size, "fixnum(%" MRB_PRId ")", mrb_fixnum(object));17 #ifndef MRB_WITHOUT_FLOAT 18 else if (mrb_float_p(object)) { 19 strncpy(string, "float", size-1); 21 20 } 22 else if (mrb_string_p(object)) 23 { 24 snprintf(string, size, "string(%s)", mrb_string_value_cstr(mrb, &object)); 21 #endif 22 else if (mrb_string_p(object)) { 23 strncpy(string, "string", size-1); 24 } 25 else { 26 strncpy(string, "anything", size-1); 25 27 } 26 28 … … 48 50 if (mrb_obj_class(mrb, object) != mrb_class_get(mrb, "InlineStructTest")) 49 51 { 50 mrb_raise f(mrb, E_TYPE_ERROR, "Expected InlineStructTest");52 mrb_raise(mrb, E_TYPE_ERROR, "Expected InlineStructTest"); 51 53 } 52 54 return mrb_bool_value(((char*)mrb_istruct_ptr(object))[0] == 's'); -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-inline-struct/test/inline.rb
r331 r439 18 18 assert('InlineStructTest#dup') do 19 19 obj = InlineStructTest.new(1) 20 assert_equal obj.to_s, 'fixnum (1)'21 assert_equal obj.dup.to_s, 'fixnum (1)'20 assert_equal obj.to_s, 'fixnum' 21 assert_equal obj.dup.to_s, 'fixnum' 22 22 end 23 23 24 24 assert('InlineStructTest#clone') do 25 25 obj = InlineStructTest.new(1) 26 assert_equal obj.to_s, 'fixnum (1)'27 assert_equal obj.clone.to_s, 'fixnum (1)'26 assert_equal obj.to_s, 'fixnum' 27 assert_equal obj.clone.to_s, 'fixnum' 28 28 end 29 29 … … 39 39 assert('InlineStructTest#mutate (dup)') do 40 40 obj1 = InlineStructTest.new("foo") 41 assert_equal obj1.to_s, "string (foo)"41 assert_equal obj1.to_s, "string" 42 42 obj2 = obj1.dup 43 assert_equal obj2.to_s, "string (foo)"43 assert_equal obj2.to_s, "string" 44 44 obj1.mutate 45 assert_equal obj1.to_s, "mutate (foo)"46 assert_equal obj2.to_s, "string (foo)"45 assert_equal obj1.to_s, "mutate" 46 assert_equal obj2.to_s, "string" 47 47 end 48 48 49 49 assert('InlineStructTest#mutate (clone)') do 50 50 obj1 = InlineStructTest.new("foo") 51 assert_equal obj1.to_s, "string (foo)"51 assert_equal obj1.to_s, "string" 52 52 obj2 = obj1.clone 53 assert_equal obj2.to_s, "string (foo)"53 assert_equal obj2.to_s, "string" 54 54 obj1.mutate 55 assert_equal obj1.to_s, "mutate (foo)"56 assert_equal obj2.to_s, "string (foo)"55 assert_equal obj1.to_s, "mutate" 56 assert_equal obj2.to_s, "string" 57 57 end 58 58 … … 102 102 assert_equal InlineStructTest.length, 3 * 8 103 103 end 104 105 assert('InlineStructTest w/float [64 bit]') do106 obj = InlineStructTest.new(1.25)107 assert_equal obj.to_s, "float(1.250)"108 end109 110 assert('InlineStructTest w/fixnum [64 bit]') do111 obj = InlineStructTest.new(42)112 assert_equal obj.to_s, "fixnum(42)"113 end114 115 assert('InlineStructTest w/string [64 bit]') do116 obj = InlineStructTest.new("hello")117 assert_equal obj.to_s, "string(hello)"118 end119 120 assert('InlineStructTest w/long string [64 bit]') do121 obj = InlineStructTest.new("this won't fit in 3 * 8 bytes available for the structure")122 assert_equal obj.to_s, "string(this won't fit i"123 end124 104 end 125 105 … … 129 109 assert_equal InlineStructTest.length, 3 * 4 130 110 end 111 end 131 112 132 assert('InlineStructTest w/float [32 bit]') do 133 obj = InlineStructTest.new(1.25) 134 assert_equal obj.to_s, "float(1.250" 135 end 136 137 assert('InlineStructTest w/fixnum [32 bit]') do 138 obj = InlineStructTest.new(42) 139 assert_equal obj.to_s, "fixnum(42)" 140 end 141 142 assert('InlineStructTest w/string [32 bit]') do 143 obj = InlineStructTest.new("hello") 144 assert_equal obj.to_s, "string(hell" 145 end 146 147 assert('InlineStructTest w/long string [32 bit]') do 148 obj = InlineStructTest.new("this won't fit in 3 * 4 bytes available for the structure") 149 assert_equal obj.to_s, "string(this" 113 # 16-bit mode 114 if InlineStructTest.length == 6 115 assert('InlineStructTest length [16 bit]') do 116 assert_equal InlineStructTest.length, 3 * 2 150 117 end 151 118 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-kernel-ext/mrbgem.rake
r321 r439 2 2 spec.license = 'MIT' 3 3 spec.author = 'mruby developers' 4 spec.summary = ' Kernel module extension'4 spec.summary = 'extensional function-like methods' 5 5 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-kernel-ext/src/kernel.c
r331 r439 21 21 break; 22 22 case 1: 23 if (mrb_ type(v) == MRB_TT_RANGE) {23 if (mrb_range_p(v)) { 24 24 mrb_int beg, len; 25 if (mrb_range_beg_len(mrb, v, &beg, &len, bt_len, TRUE) == 1) {25 if (mrb_range_beg_len(mrb, v, &beg, &len, bt_len, TRUE) == MRB_RANGE_OK) { 26 26 lev = beg; 27 27 n = len; … … 32 32 } 33 33 else { 34 v = mrb_to_int(mrb, v); 35 lev = mrb_fixnum(v); 34 lev = mrb_int(mrb, v); 36 35 if (lev < 0) { 37 mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (% S)", v);36 mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%v)", v); 38 37 } 39 38 n = bt_len - lev; … … 41 40 break; 42 41 case 2: 43 lev = mrb_ fixnum(mrb_to_int(mrb, v));44 n = mrb_ fixnum(mrb_to_int(mrb, length));42 lev = mrb_int(mrb, v); 43 n = mrb_int(mrb, length); 45 44 if (lev < 0) { 46 mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (% S)", v);45 mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%v)", v); 47 46 } 48 47 if (n < 0) { 49 mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative size (% S)", length);48 mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative size (%v)", length); 50 49 } 51 50 break; … … 94 93 * In any case, strings should be strictly conformed to numeric 95 94 * representation. This behavior is different from that of 96 * <code>String#to_i</code>. Non string values will be converted using 97 * <code>to_int</code>, and <code>to_i</code>. Passing <code>nil</code> 98 * raises a TypeError. 95 * <code>String#to_i</code>. Non string values will be treated as integers. 96 * Passing <code>nil</code> raises a TypeError. 99 97 * 100 98 * Integer(123.999) #=> 123 … … 115 113 } 116 114 115 #ifndef MRB_WITHOUT_FLOAT 117 116 /* 118 117 * call-seq: … … 135 134 return mrb_Float(mrb, arg); 136 135 } 136 #endif 137 137 138 138 /* … … 141 141 * 142 142 * Returns <i>arg</i> as an <code>String</code>. 143 * 144 * First tries to call its <code>to_str</code> method, then its to_s method. 143 * converted using <code>to_s</code> method. 145 144 * 146 145 * String(self) #=> "main" … … 154 153 155 154 mrb_get_args(mrb, "o", &arg); 156 tmp = mrb_check_convert_type(mrb, arg, MRB_TT_STRING, "String", "to_str"); 157 if (mrb_nil_p(tmp)) { 158 tmp = mrb_check_convert_type(mrb, arg, MRB_TT_STRING, "String", "to_s"); 159 } 155 tmp = mrb_convert_type(mrb, arg, MRB_TT_STRING, "String", "to_s"); 160 156 return tmp; 161 157 } … … 165 161 * Array(arg) -> array 166 162 * 167 * Returns +arg+ as an Array. 168 * 169 * First tries to call Array#to_ary on +arg+, then Array#to_a. 163 * Returns +arg+ as an Array using to_a method. 170 164 * 171 165 * Array(1..5) #=> [1, 2, 3, 4, 5] … … 178 172 179 173 mrb_get_args(mrb, "o", &arg); 180 tmp = mrb_check_convert_type(mrb, arg, MRB_TT_ARRAY, "Array", "to_ary"); 181 if (mrb_nil_p(tmp)) { 182 tmp = mrb_check_convert_type(mrb, arg, MRB_TT_ARRAY, "Array", "to_a"); 183 } 174 tmp = mrb_check_convert_type(mrb, arg, MRB_TT_ARRAY, "Array", "to_a"); 184 175 if (mrb_nil_p(tmp)) { 185 176 return mrb_ary_new_from_values(mrb, 1, &arg); … … 193 184 * Hash(arg) -> hash 194 185 * 195 * Converts <i>arg</i> to a <code>Hash</code> by calling196 * <i>arg</i><code>.to_hash</code>. Returns an empty <code>Hash</code> when197 * <i>arg</i> is <tt>nil</tt>or <tt>[]</tt>.186 * Returns a <code>Hash</code> if <i>arg</i> is a <code>Hash</code>. 187 * Returns an empty <code>Hash</code> when <i>arg</i> is <tt>nil</tt> 188 * or <tt>[]</tt>. 198 189 * 199 190 * Hash([]) #=> {} … … 206 197 mrb_f_hash(mrb_state *mrb, mrb_value self) 207 198 { 208 mrb_value arg , tmp;209 210 mrb_get_args(mrb, "o", &arg); 211 if (mrb_nil_p(arg) ) {199 mrb_value arg; 200 201 mrb_get_args(mrb, "o", &arg); 202 if (mrb_nil_p(arg) || (mrb_array_p(arg) && RARRAY_LEN(arg) == 0)) { 212 203 return mrb_hash_new(mrb); 213 204 } 214 tmp = mrb_check_convert_type(mrb, arg, MRB_TT_HASH, "Hash", "to_hash"); 215 if (mrb_nil_p(tmp)) { 216 if (mrb_array_p(arg) && RARRAY_LEN(arg) == 0) { 217 return mrb_hash_new(mrb); 218 } 219 mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into Hash", 220 mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, arg))); 221 } 222 return tmp; 205 return mrb_ensure_hash_type(mrb, arg); 223 206 } 224 207 … … 231 214 mrb_define_module_function(mrb, krn, "caller", mrb_f_caller, MRB_ARGS_OPT(2)); 232 215 mrb_define_method(mrb, krn, "__method__", mrb_f_method, MRB_ARGS_NONE()); 233 mrb_define_module_function(mrb, krn, "Integer", mrb_f_integer, MRB_ARGS_ANY()); 216 mrb_define_module_function(mrb, krn, "Integer", mrb_f_integer, MRB_ARGS_ARG(1,1)); 217 #ifndef MRB_WITHOUT_FLOAT 234 218 mrb_define_module_function(mrb, krn, "Float", mrb_f_float, MRB_ARGS_REQ(1)); 219 #endif 235 220 mrb_define_module_function(mrb, krn, "String", mrb_f_string, MRB_ARGS_REQ(1)); 236 221 mrb_define_module_function(mrb, krn, "Array", mrb_f_array, MRB_ARGS_REQ(1)); -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-kernel-ext/test/kernel.rb
r331 r439 50 50 51 51 assert('Kernel#Integer') do 52 assert_equal(123, Integer(123.999)) 53 assert_equal(26, Integer("0x1a")) 54 assert_equal(930, Integer("0930", 10)) 55 assert_equal(7, Integer("111", 2)) 56 assert_equal(0, Integer("0")) 57 assert_equal(0, Integer("00000")) 52 assert_operator(26, :eql?, Integer("0x1a")) 53 assert_operator(930, :eql?, Integer("0930", 10)) 54 assert_operator(7, :eql?, Integer("111", 2)) 55 assert_operator(0, :eql?, Integer("0")) 56 assert_operator(0, :eql?, Integer("00000")) 57 assert_operator(123, :eql?, Integer('1_2_3')) 58 assert_operator(123, :eql?, Integer("\t\r\n\f\v 123 \t\r\n\f\v")) 58 59 assert_raise(TypeError) { Integer(nil) } 60 assert_raise(ArgumentError) { Integer('a') } 61 assert_raise(ArgumentError) { Integer('4a5') } 62 assert_raise(ArgumentError) { Integer('1_2__3') } 63 assert_raise(ArgumentError) { Integer('68_') } 64 assert_raise(ArgumentError) { Integer('68_ ') } 65 assert_raise(ArgumentError) { Integer('_68') } 66 assert_raise(ArgumentError) { Integer(' _68') } 67 assert_raise(ArgumentError) { Integer('6 8') } 68 assert_raise(ArgumentError) { Integer("15\0") } 69 assert_raise(ArgumentError) { Integer("15.0") } 70 skip unless Object.const_defined?(:Float) 71 assert_operator(123, :eql?, Integer(123.999)) 59 72 end 60 73 61 74 assert('Kernel#Float') do 62 assert_equal(1.0, Float(1)) 63 assert_equal(123.456, Float(123.456)) 64 assert_equal(123.456, Float("123.456")) 75 skip unless Object.const_defined?(:Float) 76 assert_operator(1.0, :eql?, Float(1)) 77 assert_operator(123.456, :eql?, Float(123.456)) 78 assert_operator(123.456, :eql?, Float("123.456")) 79 assert_operator(123.0, :eql?, Float('1_2_3')) 80 assert_operator(12.34, :eql?, Float('1_2.3_4')) 81 assert_operator(0.9, :eql?, Float('.9')) 82 assert_operator(0.9, :eql?, Float(" \t\r\n\f\v.9 \t\r\n\f\v")) 83 assert_operator(16.0, :eql?, Float("0x10")) 65 84 assert_raise(TypeError) { Float(nil) } 85 assert_raise(ArgumentError) { Float("1. 5") } 86 assert_raise(ArgumentError) { Float("1.5a") } 87 assert_raise(ArgumentError) { Float("1.5\0") } 88 assert_raise(ArgumentError) { Float('a') } 89 assert_raise(ArgumentError) { Float('4a5') } 90 assert_raise(ArgumentError) { Float('1_2__3') } 91 assert_raise(ArgumentError) { Float('68_') } 92 assert_raise(ArgumentError) { Float('68._7') } 93 assert_raise(ArgumentError) { Float('68.7_') } 94 assert_raise(ArgumentError) { Float('68.7_ ') } 95 assert_raise(ArgumentError) { Float('_68') } 96 assert_raise(ArgumentError) { Float(' _68') } 97 assert_raise(ArgumentError) { Float('1_2.3__4') } 66 98 end 67 99 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-math/src/math.c
r331 r439 5 5 */ 6 6 7 #ifdef MRB_WITHOUT_FLOAT 8 # error Math conflicts 'MRB_WITHOUT_FLOAT' configuration in your 'build_config.rb' 9 #endif 10 7 11 #include <mruby.h> 8 12 #include <mruby/array.h> … … 15 19 struct RClass *math = mrb_module_get(mrb, "Math"); 16 20 struct RClass *domainerror = mrb_class_get_under(mrb, math, "DomainError"); 17 mrb_value str = mrb_str_new_cstr(mrb, func); 18 mrb_raisef(mrb, domainerror, "Numerical argument is out of domain - %S", str); 21 mrb_raisef(mrb, domainerror, "Numerical argument is out of domain - %s", func); 19 22 } 20 23 … … 23 26 24 27 #include <float.h> 25 26 #define MATH_TOLERANCE 1E-1227 28 28 29 double … … 123 124 sum += term/(2*j+1); 124 125 ++j; 125 } while (fabs(term/sum) > MATH_TOLERANCE); 126 if (sum == 0) break; 127 } while (fabs(term/sum) > DBL_EPSILON); 126 128 return two_sqrtpi*sum; 127 129 } … … 156 158 q1 = q2; 157 159 q2 = b/d; 158 } while (fabs(q1-q2)/q2 > MATH_TOLERANCE);160 } while (fabs(q1-q2)/q2 > DBL_EPSILON); 159 161 return one_sqrtpi*exp(-x*x)*q2; 160 162 } 161 163 164 #endif 165 166 #if defined __FreeBSD__ && !defined __FreeBSD_version 167 #include <osreldate.h> /* for __FreeBSD_version */ 162 168 #endif 163 169 … … 487 493 { 488 494 mrb_float x, base; 489 int argc;495 mrb_int argc; 490 496 491 497 argc = mrb_get_args(mrb, "f|f", &x, &base); … … 658 664 659 665 mrb_get_args(mrb, "fi", &x, &i); 660 x = ldexp(x, i);666 x = ldexp(x, (int)i); 661 667 662 668 return mrb_float_value(mrb, x); … … 737 743 #else 738 744 mrb_define_const(mrb, mrb_math, "E", mrb_float_value(mrb, exp(1.0))); 739 #endif740 741 #ifdef MRB_USE_FLOAT742 mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(mrb, 1e-5));743 #else744 mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(mrb, 1e-12));745 745 #endif 746 746 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-math/test/math.rb
r321 r439 2 2 # Math Test 3 3 4 ## 5 # Performs fuzzy check for equality on methods returning floats 6 # on the basis of the Math::TOLERANCE constant. 7 def check_float(a, b) 8 tolerance = Math::TOLERANCE 9 a = a.to_f 10 b = b.to_f 11 if a.finite? and b.finite? 12 (a-b).abs < tolerance 13 else 14 true 4 def assert_float_and_int(exp_ary, act_ary) 5 assert('assert_float_and_int') do 6 flo_exp, int_exp, flo_act, int_act = *exp_ary, *act_ary 7 assert_float(flo_exp, flo_act) 8 assert_operator(int_exp, :eql?, int_act) 15 9 end 16 10 end 17 11 18 12 assert('Math.sin 0') do 19 check_float(Math.sin(0), 0)13 assert_float(0, Math.sin(0)) 20 14 end 21 15 22 16 assert('Math.sin PI/2') do 23 check_float(Math.sin(Math::PI / 2), 1)17 assert_float(1, Math.sin(Math::PI / 2)) 24 18 end 25 19 26 20 assert('Math.cos 0') do 27 check_float(Math.cos(0), 1)21 assert_float(1, Math.cos(0)) 28 22 end 29 23 30 24 assert('Math.cos PI/2') do 31 check_float(Math.cos(Math::PI / 2), 0)25 assert_float(0, Math.cos(Math::PI / 2)) 32 26 end 33 27 34 28 assert('Math.tan 0') do 35 check_float(Math.tan(0), 0)29 assert_float(0, Math.tan(0)) 36 30 end 37 31 38 32 assert('Math.tan PI/4') do 39 check_float(Math.tan(Math::PI / 4), 1)33 assert_float(1, Math.tan(Math::PI / 4)) 40 34 end 41 35 42 36 assert('Fundamental trig identities') do 43 result = true44 37 N = 13 45 38 N.times do |i| … … 49 42 c = Math.cos(a) 50 43 t = Math.tan(a) 51 result &= check_float(s, Math.cos(ca)) 52 result &= check_float(t, 1 / Math.tan(ca)) 53 result &= check_float(s ** 2 + c ** 2, 1) 54 result &= check_float(t ** 2 + 1, (1/c) ** 2) 55 result &= check_float((1/t) ** 2 + 1, (1/s) ** 2) 56 end 57 result 44 assert_float(Math.cos(ca), s) 45 assert_float(1 / Math.tan(ca), t) 46 assert_float(1, s ** 2 + c ** 2) 47 assert_float((1/c) ** 2, t ** 2 + 1) 48 assert_float((1/s) ** 2, (1/t) ** 2 + 1) 49 end 58 50 end 59 51 60 52 assert('Math.erf 0') do 61 check_float(Math.erf(0), 0)53 assert_float(0, Math.erf(0)) 62 54 end 63 55 64 56 assert('Math.exp 0') do 65 check_float(Math.exp(0), 1.0)57 assert_float(1.0, Math.exp(0)) 66 58 end 67 59 68 60 assert('Math.exp 1') do 69 check_float(Math.exp(1), 2.718281828459045)61 assert_float(2.718281828459045, Math.exp(1)) 70 62 end 71 63 72 64 assert('Math.exp 1.5') do 73 check_float(Math.exp(1.5), 4.4816890703380645)65 assert_float(4.4816890703380645, Math.exp(1.5)) 74 66 end 75 67 76 68 assert('Math.log 1') do 77 check_float(Math.log(1), 0)69 assert_float(0, Math.log(1)) 78 70 end 79 71 80 72 assert('Math.log E') do 81 check_float(Math.log(Math::E), 1.0)73 assert_float(1.0, Math.log(Math::E)) 82 74 end 83 75 84 76 assert('Math.log E**3') do 85 check_float(Math.log(Math::E**3), 3.0)77 assert_float(3.0, Math.log(Math::E**3)) 86 78 end 87 79 88 80 assert('Math.log2 1') do 89 check_float(Math.log2(1), 0.0)81 assert_float(0.0, Math.log2(1)) 90 82 end 91 83 92 84 assert('Math.log2 2') do 93 check_float(Math.log2(2), 1.0)85 assert_float(1.0, Math.log2(2)) 94 86 end 95 87 96 88 assert('Math.log10 1') do 97 check_float(Math.log10(1), 0.0)89 assert_float(0.0, Math.log10(1)) 98 90 end 99 91 100 92 assert('Math.log10 10') do 101 check_float(Math.log10(10), 1.0)93 assert_float(1.0, Math.log10(10)) 102 94 end 103 95 104 96 assert('Math.log10 10**100') do 105 check_float(Math.log10(10**100), 100.0)97 assert_float(100.0, Math.log10(10**100)) 106 98 end 107 99 … … 109 101 num = [0.0, 1.0, 2.0, 3.0, 4.0] 110 102 sqr = [0, 1, 4, 9, 16] 111 result = true112 103 sqr.each_with_index do |v,i| 113 result &= check_float(Math.sqrt(v), num[i]) 114 end 115 result 104 assert_float(num[i], Math.sqrt(v)) 105 end 116 106 end 117 107 … … 119 109 num = [-2.0, -1.0, 0.0, 1.0, 2.0] 120 110 cub = [-8, -1, 0, 1, 8] 121 result = true122 111 cub.each_with_index do |v,i| 123 result &= check_float(Math.cbrt(v), num[i]) 124 end 125 result 112 assert_float(num[i], Math.cbrt(v)) 113 end 126 114 end 127 115 128 116 assert('Math.hypot') do 129 check_float(Math.hypot(3, 4), 5.0) 130 end 131 132 assert('Math.frexp 1234') do 133 n = 1234 134 fraction, exponent = Math.frexp(n) 135 check_float(Math.ldexp(fraction, exponent), n) 117 assert_float(5.0, Math.hypot(3, 4)) 136 118 end 137 119 138 120 assert('Math.erf 1') do 139 check_float(Math.erf(1), 0.842700792949715)121 assert_float(0.842700792949715, Math.erf(1)) 140 122 end 141 123 142 124 assert('Math.erfc 1') do 143 check_float(Math.erfc(1), 0.157299207050285)125 assert_float(0.157299207050285, Math.erfc(1)) 144 126 end 145 127 146 128 assert('Math.erf -1') do 147 check_float(Math.erf(-1), -0.8427007929497148)129 assert_float(-0.8427007929497148, Math.erf(-1)) 148 130 end 149 131 150 132 assert('Math.erfc -1') do 151 check_float(Math.erfc(-1), 1.8427007929497148) 152 end 133 assert_float(1.8427007929497148, Math.erfc(-1)) 134 end 135 136 assert('Math.acos') do 137 assert_float(0 * Math::PI / 4, Math.acos( 1.0)) 138 assert_float(1 * Math::PI / 4, Math.acos( 1.0 / Math.sqrt(2))) 139 assert_float(2 * Math::PI / 4, Math.acos( 0.0)) 140 assert_float(4 * Math::PI / 4, Math.acos(-1.0)) 141 assert_raise(Math::DomainError) { Math.acos(+1.1) } 142 assert_raise(Math::DomainError) { Math.acos(-1.1) } 143 end 144 145 assert('Math.asin') do 146 assert_float( 0 * Math::PI / 4, Math.asin( 0.0)) 147 assert_float( 1 * Math::PI / 4, Math.asin( 1.0 / Math.sqrt(2))) 148 assert_float( 2 * Math::PI / 4, Math.asin( 1.0)) 149 assert_float(-2 * Math::PI / 4, Math.asin(-1.0)) 150 assert_raise(Math::DomainError) { Math.asin(+1.1) } 151 assert_raise(Math::DomainError) { Math.asin(-1.1) } 152 assert_raise(Math::DomainError) { Math.asin(2.0) } 153 end 154 155 assert('Math.atan') do 156 assert_float( 0 * Math::PI / 4, Math.atan( 0.0)) 157 assert_float( 1 * Math::PI / 4, Math.atan( 1.0)) 158 assert_float( 2 * Math::PI / 4, Math.atan(1.0 / 0.0)) 159 assert_float(-1 * Math::PI / 4, Math.atan(-1.0)) 160 end 161 162 assert('Math.cosh') do 163 assert_float(1, Math.cosh(0)) 164 assert_float((Math::E ** 1 + Math::E ** -1) / 2, Math.cosh(1)) 165 assert_float((Math::E ** 2 + Math::E ** -2) / 2, Math.cosh(2)) 166 end 167 168 assert('Math.sinh') do 169 assert_float(0, Math.sinh(0)) 170 assert_float((Math::E ** 1 - Math::E ** -1) / 2, Math.sinh(1)) 171 assert_float((Math::E ** 2 - Math::E ** -2) / 2, Math.sinh(2)) 172 end 173 174 assert('Math.tanh') do 175 assert_float(Math.sinh(0) / Math.cosh(0), Math.tanh(0)) 176 assert_float(Math.sinh(1) / Math.cosh(1), Math.tanh(1)) 177 assert_float(Math.sinh(2) / Math.cosh(2), Math.tanh(2)) 178 assert_float(+1.0, Math.tanh(+1000.0)) 179 assert_float(-1.0, Math.tanh(-1000.0)) 180 end 181 182 assert('Math.acosh') do 183 assert_float(0, Math.acosh(1)) 184 assert_float(1, Math.acosh((Math::E ** 1 + Math::E ** -1) / 2)) 185 assert_float(2, Math.acosh((Math::E ** 2 + Math::E ** -2) / 2)) 186 assert_raise(Math::DomainError) { Math.acosh(0.9) } 187 assert_raise(Math::DomainError) { Math.acosh(0) } 188 end 189 190 assert('Math.asinh') do 191 assert_float(0, Math.asinh(0)) 192 assert_float(1, Math.asinh((Math::E ** 1 - Math::E ** -1) / 2)) 193 assert_float(2, Math.asinh((Math::E ** 2 - Math::E ** -2) / 2)) 194 end 195 196 assert('Math.atanh') do 197 assert_float(0, Math.atanh(Math.sinh(0) / Math.cosh(0))) 198 assert_float(1, Math.atanh(Math.sinh(1) / Math.cosh(1))) 199 assert_float(2, Math.atanh(Math.sinh(2) / Math.cosh(2))) 200 assert_float(Float::INFINITY, Math.atanh(1)) 201 assert_float(-Float::INFINITY, Math.atanh(-1)) 202 assert_raise(Math::DomainError) { Math.atanh(+1.1) } 203 assert_raise(Math::DomainError) { Math.atanh(-1.1) } 204 end 205 206 assert('Math.atan2') do 207 assert_float(+0.0, Math.atan2(+0.0, +0.0)) 208 assert_float(-0.0, Math.atan2(-0.0, +0.0)) 209 assert_float(+Math::PI, Math.atan2(+0.0, -0.0)) 210 assert_float(-Math::PI, Math.atan2(-0.0, -0.0)) 211 212 inf = Float::INFINITY 213 expected = 3.0 * Math::PI / 4.0 214 assert_float(+expected, Math.atan2(+inf, -inf)) 215 assert_float(-expected, Math.atan2(-inf, -inf)) 216 expected = Math::PI / 4.0 217 assert_float(+expected, Math.atan2(+inf, +inf)) 218 assert_float(-expected, Math.atan2(-inf, +inf)) 219 220 assert_float(0, Math.atan2(0, 1)) 221 assert_float(Math::PI / 4, Math.atan2(1, 1)) 222 assert_float(Math::PI / 2, Math.atan2(1, 0)) 223 end 224 225 assert('Math.ldexp') do 226 assert_float(0.0, Math.ldexp(0.0, 0.0)) 227 assert_float(0.5, Math.ldexp(0.5, 0.0)) 228 assert_float(1.0, Math.ldexp(0.5, 1.0)) 229 assert_float(2.0, Math.ldexp(0.5, 2.0)) 230 assert_float(3.0, Math.ldexp(0.75, 2.0)) 231 end 232 233 assert('Math.frexp') do 234 assert_float_and_int([0.0, 0], Math.frexp(0.0)) 235 assert_float_and_int([0.5, 0], Math.frexp(0.5)) 236 assert_float_and_int([0.5, 1], Math.frexp(1.0)) 237 assert_float_and_int([0.5, 2], Math.frexp(2.0)) 238 assert_float_and_int([0.75, 2], Math.frexp(3.0)) 239 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb
r331 r439 1 module Integral 2 def div(other) 3 self.divmod(other)[0] 4 end 5 1 class Numeric 6 2 def zero? 7 3 self == 0 … … 15 11 end 16 12 end 13 14 def positive? 15 self > 0 16 end 17 18 def negative? 19 self < 0 20 end 17 21 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-numeric-ext/src/numeric_ext.c
r331 r439 1 1 #include <limits.h> 2 2 #include <mruby.h> 3 #include <mruby/numeric.h> 3 4 5 /* 6 * call-seq: 7 * int.allbits?(mask) -> true or false 8 * 9 * Returns +true+ if all bits of <code>+int+ & +mask+</code> are 1. 10 */ 4 11 static mrb_value 5 mrb_int_ chr(mrb_state *mrb, mrb_value x)12 mrb_int_allbits(mrb_state *mrb, mrb_value self) 6 13 { 7 mrb_int chr; 8 char c; 14 mrb_int n, m; 9 15 10 chr = mrb_fixnum(x); 11 if (chr >= (1 << CHAR_BIT)) { 12 mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", x); 13 } 14 c = (char)chr; 16 mrb_get_args(mrb, "i", &m); 17 n = mrb_int(mrb, self); 18 return mrb_bool_value((n & m) == m); 19 } 15 20 16 return mrb_str_new(mrb, &c, 1); 21 /* 22 * call-seq: 23 * int.anybits?(mask) -> true or false 24 * 25 * Returns +true+ if any bits of <code>+int+ & +mask+</code> are 1. 26 */ 27 static mrb_value 28 mrb_int_anybits(mrb_state *mrb, mrb_value self) 29 { 30 mrb_int n, m; 31 32 mrb_get_args(mrb, "i", &m); 33 n = mrb_int(mrb, self); 34 return mrb_bool_value((n & m) != 0); 35 } 36 37 /* 38 * call-seq: 39 * int.nobits?(mask) -> true or false 40 * 41 * Returns +true+ if no bits of <code>+int+ & +mask+</code> are 1. 42 */ 43 static mrb_value 44 mrb_int_nobits(mrb_state *mrb, mrb_value self) 45 { 46 mrb_int n, m; 47 48 mrb_get_args(mrb, "i", &m); 49 n = mrb_int(mrb, self); 50 return mrb_bool_value((n & m) == 0); 17 51 } 18 52 … … 20 54 mrb_mruby_numeric_ext_gem_init(mrb_state* mrb) 21 55 { 22 struct RClass *i = mrb_ class_get(mrb, "Integer");56 struct RClass *i = mrb_module_get(mrb, "Integral"); 23 57 24 mrb_define_method(mrb, i, "chr", mrb_int_chr, MRB_ARGS_NONE()); 58 mrb_define_method(mrb, i, "allbits?", mrb_int_allbits, MRB_ARGS_REQ(1)); 59 mrb_define_method(mrb, i, "anybits?", mrb_int_anybits, MRB_ARGS_REQ(1)); 60 mrb_define_method(mrb, i, "nobits?", mrb_int_nobits, MRB_ARGS_REQ(1)); 61 62 #ifndef MRB_WITHOUT_FLOAT 63 mrb_define_const(mrb, mrb->float_class, "RADIX", mrb_fixnum_value(MRB_FLT_RADIX)); 64 mrb_define_const(mrb, mrb->float_class, "MANT_DIG", mrb_fixnum_value(MRB_FLT_MANT_DIG)); 65 mrb_define_const(mrb, mrb->float_class, "EPSILON", mrb_float_value(mrb, MRB_FLT_EPSILON)); 66 mrb_define_const(mrb, mrb->float_class, "DIG", mrb_fixnum_value(MRB_FLT_DIG)); 67 mrb_define_const(mrb, mrb->float_class, "MIN_EXP", mrb_fixnum_value(MRB_FLT_MIN_EXP)); 68 mrb_define_const(mrb, mrb->float_class, "MIN", mrb_float_value(mrb, MRB_FLT_MIN)); 69 mrb_define_const(mrb, mrb->float_class, "MIN_10_EXP", mrb_fixnum_value(MRB_FLT_MIN_10_EXP)); 70 mrb_define_const(mrb, mrb->float_class, "MAX_EXP", mrb_fixnum_value(MRB_FLT_MAX_EXP)); 71 mrb_define_const(mrb, mrb->float_class, "MAX", mrb_float_value(mrb, MRB_FLT_MAX)); 72 mrb_define_const(mrb, mrb->float_class, "MAX_10_EXP", mrb_fixnum_value(MRB_FLT_MAX_10_EXP)); 73 #endif /* MRB_WITHOUT_FLOAT */ 25 74 } 26 75 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-numeric-ext/test/numeric.rb
r331 r439 1 1 ## 2 2 # Numeric(Ext) Test 3 4 assert('Integer#chr') do5 assert_equal("A", 65.chr)6 assert_equal("B", 0x42.chr)7 8 # multibyte encoding (not support yet)9 assert_raise(RangeError) { 256.chr }10 end11 3 12 4 assert('Integer#div') do … … 15 7 16 8 assert('Float#div') do 9 skip unless Object.const_defined?(:Float) 17 10 assert_float 52, 365.2425.div(7) 18 11 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-object-ext/mrbgem.rake
r321 r439 2 2 spec.license = 'MIT' 3 3 spec.author = 'mruby developers' 4 spec.summary = ' Object class extension'4 spec.summary = 'extensional methods shared by all objects' 5 5 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-object-ext/mrblib/object.rb
r321 r439 1 class Object 1 module Kernel 2 # call-seq: 3 # obj.yield_self {|_obj|...} -> an_object 4 # obj.then {|_obj|...} -> an_object 5 # 6 # Yields <i>obj</i> and returns the result. 7 # 8 # 'my string'.yield_self {|s|s.upcase} #=> "MY STRING" 9 # 10 def yield_self(&block) 11 return to_enum :yield_self unless block 12 block.call(self) 13 end 14 alias then yield_self 15 2 16 ## 3 17 # call-seq: -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-object-ext/src/object.c
r331 r439 2 2 #include <mruby/array.h> 3 3 #include <mruby/class.h> 4 #include <mruby/hash.h> 4 5 #include <mruby/proc.h> 5 6 … … 17 18 } 18 19 20 #ifndef MRB_WITHOUT_FLOAT 19 21 /* 20 22 * call-seq: … … 28 30 { 29 31 return mrb_float_value(mrb, 0.0); 32 } 33 #endif 34 35 /* 36 * call-seq: 37 * nil.to_h -> {} 38 * 39 * Always returns an empty hash. 40 */ 41 42 static mrb_value 43 nil_to_h(mrb_state *mrb, mrb_value obj) 44 { 45 return mrb_hash_new(mrb); 30 46 } 31 47 … … 41 57 { 42 58 return mrb_fixnum_value(0); 59 } 60 61 /* 62 * call-seq: 63 * obj.itself -> an_object 64 * 65 * Returns <i>obj</i>. 66 * 67 * string = 'my string' #=> "my string" 68 * string.itself.object_id == string.object_id #=> true 69 * 70 */ 71 static mrb_value 72 mrb_f_itself(mrb_state *mrb, mrb_value self) 73 { 74 return self; 43 75 } 44 76 … … 68 100 mrb_value blk; 69 101 struct RClass *c; 70 mrb_value args;71 102 72 mrb_get_args(mrb, "*&", &argv, &argc, &blk); 73 74 if (mrb_nil_p(blk)) { 75 mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); 76 } 103 mrb_get_args(mrb, "*&!", &argv, &argc, &blk); 77 104 78 105 switch (mrb_type(self)) { 79 106 case MRB_TT_SYMBOL: 80 107 case MRB_TT_FIXNUM: 108 #ifndef MRB_WITHOUT_FLOAT 81 109 case MRB_TT_FLOAT: 110 #endif 82 111 c = NULL; 83 112 break; … … 86 115 break; 87 116 } 88 args = mrb_ary_new_from_values(mrb, argc, argv);89 argv = RARRAY_PTR(args);90 117 mrb->c->ci->target_class = c; 91 118 return mrb_yield_cont(mrb, blk, self, argc, argv); … … 98 125 99 126 mrb_define_method(mrb, n, "to_a", nil_to_a, MRB_ARGS_NONE()); 127 #ifndef MRB_WITHOUT_FLOAT 100 128 mrb_define_method(mrb, n, "to_f", nil_to_f, MRB_ARGS_NONE()); 129 #endif 130 mrb_define_method(mrb, n, "to_h", nil_to_h, MRB_ARGS_NONE()); 101 131 mrb_define_method(mrb, n, "to_i", nil_to_i, MRB_ARGS_NONE()); 102 132 103 mrb_define_method(mrb, mrb->kernel_module, "instance_exec", mrb_obj_instance_exec, MRB_ARGS_ANY() | MRB_ARGS_BLOCK()); 133 mrb_define_method(mrb, mrb->kernel_module, "itself", mrb_f_itself, MRB_ARGS_NONE()); 134 135 mrb_define_method(mrb, mrb_class_get(mrb, "BasicObject"), "instance_exec", mrb_obj_instance_exec, MRB_ARGS_ANY() | MRB_ARGS_BLOCK()); 104 136 } 105 137 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-object-ext/test/nil.rb
r321 r439 4 4 5 5 assert('NilClass#to_f') do 6 skip unless Object.const_defined?(:Float) 6 7 assert_equal 0.0, nil.to_f 8 end 9 10 assert('NilClass#to_h') do 11 assert_equal Hash.new, nil.to_h 7 12 end 8 13 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-objectspace/src/mruby_objectspace.c
r331 r439 58 58 } 59 59 60 if (!mrb_ test(mrb_hash_empty_p(mrb, hash))) {60 if (!mrb_hash_empty_p(mrb, hash)) { 61 61 mrb_hash_clear(mrb, hash); 62 62 } … … 162 162 mrb_value cls = mrb_nil_value(); 163 163 struct os_each_object_data d; 164 mrb_get_args(mrb, "&|C", &d.block, &cls); 165 166 if (mrb_nil_p(d.block)) { 167 mrb_raise(mrb, E_ARGUMENT_ERROR, "Expected block in ObjectSpace.each_object."); 168 } 164 mrb_get_args(mrb, "&!|C", &d.block, &cls); 169 165 170 166 d.target_module = mrb_nil_p(cls) ? NULL : mrb_class_ptr(cls); -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-objectspace/test/objectspace.rb
r321 r439 1 1 assert('ObjectSpace.count_objects') do 2 2 h = {} 3 f = Fiber.new {} if Object.const_defined? :Fiber3 f = Fiber.new {} if Object.const_defined?(:Fiber) 4 4 ObjectSpace.count_objects(h) 5 5 assert_kind_of(Hash, h) … … 32 32 objs << {} 33 33 end 34 ObjectSpace.count_objects(h) 34 35 objs = nil 35 ObjectSpace.count_objects(h)36 36 GC.start 37 37 ObjectSpace.count_objects(h_after) … … 57 57 58 58 assert 'Check class pointer of ObjectSpace.each_object.' do 59 ObjectSpace.each_object { |obj| !obj}59 assert_nothing_raised { ObjectSpace.each_object { |obj| !obj } } 60 60 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-print/mrblib/print.rb
r321 r439 46 46 i += 1 47 47 end 48 args [0]48 args.__svalue 49 49 end 50 50 51 unless Kernel.respond_to?(:sprintf) 52 def printf(*args) 53 raise NotImplementedError.new('printf not available') 54 end 55 def sprintf(*args) 56 raise NotImplementedError.new('sprintf not available') 57 end 58 else 59 def printf(*args) 60 __printstr__(sprintf(*args)) 61 nil 62 end 51 def printf(*args) 52 __printstr__(sprintf(*args)) 53 nil 63 54 end 64 55 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-print/src/print.c
r331 r439 1 1 #include <mruby.h> 2 3 #ifdef MRB_DISABLE_STDIO 4 # error print conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb' 5 #endif 6 2 7 #include <mruby/string.h> 3 #include <stdio.h>4 8 #include <string.h> 5 9 #include <stdlib.h> … … 20 24 if (isatty(fileno(stdout))) { 21 25 DWORD written; 22 int mlen = RSTRING_LEN(obj);26 int mlen = (int)RSTRING_LEN(obj); 23 27 char* utf8 = RSTRING_PTR(obj); 24 28 int wlen = MultiByteToWideChar(CP_UTF8, 0, utf8, mlen, NULL, 0); 25 29 wchar_t* utf16 = (wchar_t*)mrb_malloc(mrb, (wlen+1) * sizeof(wchar_t)); 26 if (utf16 == NULL) return;27 30 if (MultiByteToWideChar(CP_UTF8, 0, utf8, mlen, utf16, wlen) > 0) { 28 31 utf16[wlen] = 0; … … 34 37 #endif 35 38 fwrite(RSTRING_PTR(obj), RSTRING_LEN(obj), 1, stdout); 39 fflush(stdout); 36 40 } 37 41 } -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-proc-ext/mrblib/proc.rb
r321 r439 28 28 pproc = self 29 29 make_curry = proc do |given_args=[]| 30 send(type) do |*args|30 __send__(type) do |*args| 31 31 new_args = given_args + args 32 32 if new_args.size >= arity … … 40 40 end 41 41 42 def <<(other) 43 ->(*args, &block) { call(other.call(*args, &block)) } 44 end 45 46 def >>(other) 47 ->(*args, &block) { other.call(call(*args, &block)) } 48 end 49 42 50 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-proc-ext/src/proc.c
r331 r439 26 26 const char *filename; 27 27 28 filename = mrb_debug_get_filename( irep, 0);29 line = mrb_debug_get_line( irep, 0);28 filename = mrb_debug_get_filename(mrb, irep, 0); 29 line = mrb_debug_get_line(mrb, irep, 0); 30 30 31 31 return (!filename && line == -1)? mrb_nil_value() … … 39 39 struct RProc *p = mrb_proc_ptr(self); 40 40 mrb_value str = mrb_str_new_lit(mrb, "#<Proc:"); 41 mrb_str_c oncat(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(self)));41 mrb_str_cat_str(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(self))); 42 42 43 43 if (!MRB_PROC_CFUNC_P(p)) { … … 47 47 mrb_str_cat_lit(mrb, str, "@"); 48 48 49 filename = mrb_debug_get_filename( irep, 0);49 filename = mrb_debug_get_filename(mrb, irep, 0); 50 50 mrb_str_cat_cstr(mrb, str, filename ? filename : "-"); 51 51 mrb_str_cat_lit(mrb, str, ":"); 52 52 53 line = mrb_debug_get_line( irep, 0);53 line = mrb_debug_get_line(mrb, irep, 0); 54 54 if (line != -1) { 55 str = mrb_format(mrb, "%S:%S", str, mrb_fixnum_value(line));55 mrb_str_concat(mrb, str, mrb_fixnum_value(line)); 56 56 } 57 57 else { … … 73 73 mrb_value blk; 74 74 75 mrb_get_args(mrb, "&", &blk); 76 if (mrb_nil_p(blk)) { 77 mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block"); 78 } 75 mrb_get_args(mrb, "&!", &blk); 79 76 80 77 return blk; … … 95 92 { 96 93 struct parameters_type { 94 size_t len; 95 const char *name; 97 96 int size; 98 const char *name;99 97 } *p, parameters_list [] = { 100 { 0, "req"},101 { 0, "opt"},102 { 0, "rest"},103 { 0, "req"},104 { 0, "block"},105 {0, NULL }98 {sizeof("req") - 1, "req", 0}, 99 {sizeof("opt") - 1, "opt", 0}, 100 {sizeof("rest") - 1, "rest", 0}, 101 {sizeof("req") - 1, "req", 0}, 102 {sizeof("block") - 1, "block", 0}, 103 {0, NULL, 0} 106 104 }; 107 105 const struct RProc *proc = mrb_proc_ptr(self); 108 106 const struct mrb_irep *irep = proc->body.irep; 109 107 mrb_aspec aspec; 110 mrb_value sname,parameters;108 mrb_value parameters; 111 109 int i, j; 110 int max = -1; 112 111 113 112 if (MRB_PROC_CFUNC_P(proc)) { … … 121 120 return mrb_ary_new(mrb); 122 121 } 123 if ( GET_OPCODE(*irep->iseq)!= OP_ENTER) {122 if (*irep->iseq != OP_ENTER) { 124 123 return mrb_ary_new(mrb); 125 124 } 126 125 127 126 if (!MRB_PROC_STRICT_P(proc)) { 127 parameters_list[0].len = sizeof("opt") - 1; 128 128 parameters_list[0].name = "opt"; 129 parameters_list[3].len = sizeof("opt") - 1; 129 130 parameters_list[3].name = "opt"; 130 131 } 131 132 132 aspec = GETARG_Ax(*irep->iseq);133 aspec = PEEK_W(irep->iseq+1); 133 134 parameters_list[0].size = MRB_ASPEC_REQ(aspec); 134 135 parameters_list[1].size = MRB_ASPEC_OPT(aspec); … … 139 140 parameters = mrb_ary_new_capa(mrb, irep->nlocals-1); 140 141 142 max = irep->nlocals-1; 141 143 for (i = 0, p = parameters_list; p->name; p++) { 142 if (p->size <= 0) continue;143 sname = mrb_symbol_value(mrb_intern_cstr(mrb, p->name)); 144 mrb_value sname = mrb_symbol_value(mrb_intern_static(mrb, p->name, p->len)); 145 144 146 for (j = 0; j < p->size; i++, j++) { 145 mrb_value a = mrb_ary_new(mrb); 147 mrb_value a; 148 149 a = mrb_ary_new(mrb); 146 150 mrb_ary_push(mrb, a, sname); 147 if (irep->lv[i].name) { 148 mrb_ary_push(mrb, a, mrb_symbol_value(irep->lv[i].name)); 151 if (i < max && irep->lv[i].name) { 152 mrb_sym sym = irep->lv[i].name; 153 const char *name = mrb_sym_name(mrb, sym); 154 switch (name[0]) { 155 case '*': case '&': 156 break; 157 default: 158 mrb_ary_push(mrb, a, mrb_symbol_value(sym)); 159 break; 160 } 149 161 } 150 162 mrb_ary_push(mrb, parameters, a); … … 164 176 mrb_define_method(mrb, p, "parameters", mrb_proc_parameters, MRB_ARGS_NONE()); 165 177 166 mrb_define_class_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE() );167 mrb_define_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE() );178 mrb_define_class_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); 179 mrb_define_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); 168 180 } 169 181 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-proc-ext/test/proc.c
r331 r439 14 14 mrb_sym n; 15 15 mrb_value n_val; 16 mrb_method_t m; 17 struct RProc *p; 16 18 mrb_get_args(mrb, "n", &n); 17 19 n_val = mrb_symbol_value(n); 18 mrb_define_method_raw(mrb, mrb_class_ptr(self), n, 19 mrb_proc_new_cfunc_with_env(mrb, return_func_name, 1, &n_val)); 20 p = mrb_proc_new_cfunc_with_env(mrb, return_func_name, 1, &n_val); 21 MRB_METHOD_FROM_PROC(m, p); 22 mrb_define_method_raw(mrb, mrb_class_ptr(self), n, m); 20 23 return self; 21 24 } … … 34 37 mrb_sym n; 35 38 mrb_value *argv; mrb_int argc; 39 mrb_method_t m; 40 struct RProc *p; 36 41 mrb_get_args(mrb, "na", &n, &argv, &argc); 37 mrb_define_method_raw(mrb, mrb_class_ptr(self), n, 38 mrb_proc_new_cfunc_with_env(mrb, return_env, argc, argv)); 42 p = mrb_proc_new_cfunc_with_env(mrb, return_env, argc, argv); 43 MRB_METHOD_FROM_PROC(m, p); 44 mrb_define_method_raw(mrb, mrb_class_ptr(self), n, m); 39 45 return self; 40 46 } -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-proc-ext/test/proc.rb
r331 r439 2 2 # Proc(Ext) Test 3 3 4 def enable_debug_info? 5 return @enable_debug_info unless @enable_debug_info == nil 6 begin 7 raise 8 rescue => e 9 @enable_debug_info = !e.backtrace.empty? 10 end 11 end 12 4 13 assert('Proc#source_location') do 5 loc = Proc.new {}.source_location6 next true if loc.nil?7 assert_equal loc[0][-7, 7], 'proc.rb'8 assert_equal loc[1], 514 skip unless enable_debug_info? 15 file, line = Proc.new{}.source_location 16 assert_equal __FILE__, file 17 assert_equal __LINE__ - 2, line 9 18 end 10 19 11 20 assert('Proc#inspect') do 12 21 ins = Proc.new{}.inspect 13 assert_kind_of String, ins 22 if enable_debug_info? 23 metas = %w(\\ * ? [ ] { }) 24 file = __FILE__.split("").map{|c| metas.include?(c) ? "\\#{c}" : c}.join 25 line = __LINE__ - 4 26 else 27 file = line = "-" 28 end 29 assert_match "#<Proc:0x*@#{file}:#{line}>", ins 30 end 31 32 assert('Proc#parameters') do 33 parameters = Proc.new{|x,y=42,*other|}.parameters 34 assert_equal [[:opt, :x], [:opt, :y], [:rest, :other]], parameters 14 35 end 15 36 … … 67 88 assert('Kernel#proc') do 68 89 assert_true !proc{|a|}.lambda? 90 91 assert_raise LocalJumpError do 92 proc{ break }.call 93 end 94 end 95 96 assert "Proc#<< and Proc#>>" do 97 add3 = ->(n) { n + 3 } 98 mul2 = ->(n) { n * 2 } 99 100 f1 = mul2 << add3 101 assert_kind_of Proc, f1 102 assert_equal 16, f1.call(5) 103 104 f2 = mul2 >> add3 105 assert_kind_of Proc, f2 106 assert_equal 13, f2.call(5) 69 107 end 70 108 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-random/src/random.c
r331 r439 10 10 #include <mruby/data.h> 11 11 #include <mruby/array.h> 12 #include "mt19937ar.h" 12 #include <mruby/istruct.h> 13 #if INT32_MAX <= INTPTR_MAX 14 # define XORSHIFT96 15 # define NSEEDS 3 16 #else 17 # define NSEEDS 4 18 #endif 19 #define LASTSEED (NSEEDS-1) 13 20 14 21 #include <time.h> 15 22 16 static char const MT_STATE_KEY[] = "$mrb_i_mt_state"; 17 18 static const struct mrb_data_type mt_state_type = { 19 MT_STATE_KEY, mrb_free, 20 }; 21 22 static mrb_value mrb_random_rand(mrb_state *mrb, mrb_value self); 23 static mrb_value mrb_random_srand(mrb_state *mrb, mrb_value self); 23 typedef struct rand_state { 24 uint32_t seed[NSEEDS]; 25 } rand_state; 24 26 25 27 static void 26 mt_srand(mt_state *t, unsigned long seed) 27 { 28 mrb_random_init_genrand(t, seed); 29 } 30 31 static unsigned long 32 mt_rand(mt_state *t) 33 { 34 return mrb_random_genrand_int32(t); 35 } 36 28 rand_init(rand_state *t) 29 { 30 t->seed[0] = 123456789; 31 t->seed[1] = 362436069; 32 t->seed[2] = 521288629; 33 #ifndef XORSHIFT96 34 t->seed[3] = 88675123; 35 #endif 36 } 37 38 static uint32_t 39 rand_seed(rand_state *t, uint32_t seed) 40 { 41 uint32_t old_seed = t->seed[LASTSEED]; 42 rand_init(t); 43 t->seed[LASTSEED] = seed; 44 return old_seed; 45 } 46 47 #ifdef XORSHIFT96 48 static uint32_t 49 rand_uint32(rand_state *state) 50 { 51 uint32_t *seed = state->seed; 52 uint32_t x = seed[0]; 53 uint32_t y = seed[1]; 54 uint32_t z = seed[2]; 55 uint32_t t; 56 57 t = (x ^ (x << 3)) ^ (y ^ (y >> 19)) ^ (z ^ (z << 6)); 58 x = y; y = z; z = t; 59 seed[0] = x; 60 seed[1] = y; 61 seed[2] = z; 62 63 return z; 64 } 65 #else /* XORSHIFT96 */ 66 static uint32_t 67 rand_uint32(rand_state *state) 68 { 69 uint32_t *seed = state->seed; 70 uint32_t x = seed[0]; 71 uint32_t y = seed[1]; 72 uint32_t z = seed[2]; 73 uint32_t w = seed[3]; 74 uint32_t t; 75 76 t = x ^ (x << 11); 77 x = y; y = z; z = w; 78 w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)); 79 seed[0] = x; 80 seed[1] = y; 81 seed[2] = z; 82 seed[3] = w; 83 84 return w; 85 } 86 #endif /* XORSHIFT96 */ 87 88 #ifndef MRB_WITHOUT_FLOAT 37 89 static double 38 mt_rand_real(mt_state *t) 39 { 40 return mrb_random_genrand_real1(t); 41 } 42 43 static mrb_value 44 mrb_random_mt_srand(mrb_state *mrb, mt_state *t, mrb_value seed) 45 { 46 if (mrb_nil_p(seed)) { 47 seed = mrb_fixnum_value((mrb_int)(time(NULL) + mt_rand(t))); 48 if (mrb_fixnum(seed) < 0) { 49 seed = mrb_fixnum_value(0 - mrb_fixnum(seed)); 50 } 51 } 52 53 mt_srand(t, (unsigned) mrb_fixnum(seed)); 54 55 return seed; 56 } 57 58 static mrb_value 59 mrb_random_mt_rand(mrb_state *mrb, mt_state *t, mrb_value max) 90 rand_real(rand_state *t) 91 { 92 uint32_t x = rand_uint32(t); 93 return x*(1.0/4294967295.0); 94 } 95 #endif 96 97 static mrb_value 98 random_rand(mrb_state *mrb, rand_state *t, mrb_value max) 60 99 { 61 100 mrb_value value; 62 101 63 102 if (mrb_fixnum(max) == 0) { 64 value = mrb_float_value(mrb, mt_rand_real(t)); 65 } 66 else { 67 value = mrb_fixnum_value(mt_rand(t) % mrb_fixnum(max)); 103 #ifndef MRB_WITHOUT_FLOAT 104 value = mrb_float_value(mrb, rand_real(t)); 105 #else 106 mrb_raise(mrb, E_ARGUMENT_ERROR, "Float not supported"); 107 #endif 108 } 109 else { 110 value = mrb_fixnum_value(rand_uint32(t) % mrb_fixnum(max)); 68 111 } 69 112 … … 80 123 81 124 if (!mrb_nil_p(arg)) { 82 arg = mrb_check_convert_type(mrb, arg, MRB_TT_FIXNUM, "Fixnum", "to_int");83 if (mrb_nil_p(arg)) { 84 mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument type");85 }86 if ( mrb_fixnum(arg)< 0) {87 arg = mrb_fixnum_value(0 - mrb_fixnum(arg));125 mrb_int i; 126 127 arg = mrb_to_int(mrb, arg); 128 i = mrb_fixnum(arg); 129 if (i < 0) { 130 arg = mrb_fixnum_value(0 - i); 88 131 } 89 132 } … … 91 134 } 92 135 93 static mrb_value 94 get_random(mrb_state *mrb) { 95 return mrb_const_get(mrb, 96 mrb_obj_value(mrb_class_get(mrb, "Random")), 97 mrb_intern_lit(mrb, "DEFAULT")); 98 } 99 100 static mt_state * 101 get_random_state(mrb_state *mrb) 102 { 103 mrb_value random_val = get_random(mrb); 104 return DATA_GET_PTR(mrb, random_val, &mt_state_type, mt_state); 105 } 106 107 static mrb_value 108 mrb_random_g_rand(mrb_state *mrb, mrb_value self) 109 { 110 mrb_value random = get_random(mrb); 111 return mrb_random_rand(mrb, random); 112 } 113 114 static mrb_value 115 mrb_random_g_srand(mrb_state *mrb, mrb_value self) 116 { 117 mrb_value random = get_random(mrb); 118 return mrb_random_srand(mrb, random); 119 } 120 121 static mrb_value 122 mrb_random_init(mrb_state *mrb, mrb_value self) 136 static void 137 random_check(mrb_state *mrb, mrb_value random) { 138 struct RClass *c = mrb_class_get(mrb, "Random"); 139 if (!mrb_obj_is_kind_of(mrb, random, c) || !mrb_istruct_p(random)) { 140 mrb_raise(mrb, E_TYPE_ERROR, "Random instance required"); 141 } 142 } 143 144 static mrb_value 145 random_default(mrb_state *mrb) { 146 struct RClass *c = mrb_class_get(mrb, "Random"); 147 mrb_value d = mrb_const_get(mrb, mrb_obj_value(c), mrb_intern_lit(mrb, "DEFAULT")); 148 if (!mrb_obj_is_kind_of(mrb, d, c)) { 149 mrb_raise(mrb, E_TYPE_ERROR, "Random::DEFAULT replaced"); 150 } 151 return d; 152 } 153 154 #define random_ptr(v) (rand_state*)mrb_istruct_ptr(v) 155 #define random_default_state(mrb) random_ptr(random_default(mrb)) 156 157 static mrb_value 158 random_m_init(mrb_state *mrb, mrb_value self) 123 159 { 124 160 mrb_value seed; 125 mt_state *t;161 rand_state *t; 126 162 127 163 seed = get_opt(mrb); 128 129 164 /* avoid memory leaks */ 130 t = (mt_state*)DATA_PTR(self); 131 if (t) { 132 mrb_free(mrb, t); 133 } 134 mrb_data_init(self, NULL, &mt_state_type); 135 136 t = (mt_state *)mrb_malloc(mrb, sizeof(mt_state)); 137 t->mti = N + 1; 138 139 seed = mrb_random_mt_srand(mrb, t, seed); 165 t = random_ptr(self); 140 166 if (mrb_nil_p(seed)) { 141 t->has_seed = FALSE; 142 } 143 else { 144 mrb_assert(mrb_fixnum_p(seed)); 145 t->has_seed = TRUE; 146 t->seed = mrb_fixnum(seed); 147 } 148 149 mrb_data_init(self, t, &mt_state_type); 167 rand_init(t); 168 } 169 else { 170 rand_seed(t, (uint32_t)mrb_fixnum(seed)); 171 } 150 172 151 173 return self; 152 174 } 153 175 154 static void 155 mrb_random_rand_seed(mrb_state *mrb, mt_state *t) 156 { 157 if (!t->has_seed) { 158 mrb_random_mt_srand(mrb, t, mrb_nil_value()); 159 } 160 } 161 162 static mrb_value 163 mrb_random_rand(mrb_state *mrb, mrb_value self) 176 static mrb_value 177 random_m_rand(mrb_state *mrb, mrb_value self) 164 178 { 165 179 mrb_value max; 166 mt_state *t = DATA_GET_PTR(mrb, self, &mt_state_type, mt_state);180 rand_state *t = random_ptr(self); 167 181 168 182 max = get_opt(mrb); 169 mrb_random_rand_seed(mrb, t); 170 return mrb_random_mt_rand(mrb, t, max); 171 } 172 173 static mrb_value 174 mrb_random_srand(mrb_state *mrb, mrb_value self) 175 { 176 mrb_value seed; 177 mrb_value old_seed; 178 mt_state *t = DATA_GET_PTR(mrb, self, &mt_state_type, mt_state); 179 180 seed = get_opt(mrb); 181 seed = mrb_random_mt_srand(mrb, t, seed); 182 old_seed = t->has_seed? mrb_fixnum_value(t->seed) : mrb_nil_value(); 183 if (mrb_nil_p(seed)) { 184 t->has_seed = FALSE; 185 } 186 else { 187 mrb_assert(mrb_fixnum_p(seed)); 188 t->has_seed = TRUE; 189 t->seed = mrb_fixnum(seed); 190 } 191 192 return old_seed; 183 return random_rand(mrb, t, max); 184 } 185 186 static mrb_value 187 random_m_srand(mrb_state *mrb, mrb_value self) 188 { 189 uint32_t seed; 190 uint32_t old_seed; 191 mrb_value sv; 192 rand_state *t = random_ptr(self); 193 194 sv = get_opt(mrb); 195 if (mrb_nil_p(sv)) { 196 seed = (uint32_t)time(NULL) + rand_uint32(t); 197 } 198 else { 199 seed = (uint32_t)mrb_fixnum(sv); 200 } 201 old_seed = rand_seed(t, seed); 202 203 return mrb_fixnum_value((mrb_int)old_seed); 193 204 } 194 205 … … 204 215 { 205 216 mrb_int i; 206 mt_state *random = NULL; 217 mrb_value max; 218 mrb_value r = mrb_nil_value(); 219 rand_state *random; 207 220 208 221 if (RARRAY_LEN(ary) > 1) { 209 mrb_get_args(mrb, "|d", &random, &mt_state_type); 210 211 if (random == NULL) { 212 random = get_random_state(mrb); 213 } 214 mrb_random_rand_seed(mrb, random); 215 222 mrb_get_args(mrb, "|o", &r); 223 224 if (mrb_nil_p(r)) { 225 random = random_default_state(mrb); 226 } 227 else { 228 random_check(mrb, r); 229 random = random_ptr(r); 230 } 216 231 mrb_ary_modify(mrb, mrb_ary_ptr(ary)); 217 232 max = mrb_fixnum_value(RARRAY_LEN(ary)); 218 233 for (i = RARRAY_LEN(ary) - 1; i > 0; i--) { 219 234 mrb_int j; 235 mrb_value *ptr = RARRAY_PTR(ary); 220 236 mrb_value tmp; 221 237 222 j = mrb_fixnum( mrb_random_mt_rand(mrb, random, mrb_fixnum_value(RARRAY_LEN(ary))));223 224 tmp = RARRAY_PTR(ary)[i];225 mrb_ary_ptr(ary)->ptr[i] = RARRAY_PTR(ary)[j];226 mrb_ary_ptr(ary)->ptr[j] = tmp;238 j = mrb_fixnum(random_rand(mrb, random, max)); 239 240 tmp = ptr[i]; 241 ptr[i] = ptr[j]; 242 ptr[j] = tmp; 227 243 } 228 244 } … … 267 283 mrb_int n = 0; 268 284 mrb_bool given; 269 mt_state *random = NULL; 285 mrb_value r = mrb_nil_value(); 286 rand_state *random; 270 287 mrb_int len; 271 288 272 mrb_get_args(mrb, "|i?d", &n, &given, &random, &mt_state_type); 273 if (random == NULL) { 274 random = get_random_state(mrb); 275 } 276 mrb_random_rand_seed(mrb, random); 277 mt_rand(random); 289 mrb_get_args(mrb, "|i?o", &n, &given, &r); 290 if (mrb_nil_p(r)) { 291 random = random_default_state(mrb); 292 } 293 else { 294 random_check(mrb, r); 295 random = random_ptr(r); 296 } 278 297 len = RARRAY_LEN(ary); 279 298 if (!given) { /* pick one element */ … … 284 303 return RARRAY_PTR(ary)[0]; 285 304 default: 286 return RARRAY_PTR(ary)[ mt_rand(random) % len];305 return RARRAY_PTR(ary)[rand_uint32(random) % len]; 287 306 } 288 307 } … … 299 318 for (;;) { 300 319 retry: 301 r = mt_rand(random) % len;320 r = (mrb_int)(rand_uint32(random) % len); 302 321 303 322 for (j=0; j<i; j++) { … … 317 336 } 318 337 338 static mrb_value 339 random_f_rand(mrb_state *mrb, mrb_value self) 340 { 341 rand_state *t = random_default_state(mrb); 342 return random_rand(mrb, t, get_opt(mrb)); 343 } 344 345 static mrb_value 346 random_f_srand(mrb_state *mrb, mrb_value self) 347 { 348 mrb_value random = random_default(mrb); 349 return random_m_srand(mrb, random); 350 } 351 319 352 320 353 void mrb_mruby_random_gem_init(mrb_state *mrb) … … 323 356 struct RClass *array = mrb->array_class; 324 357 325 mrb_define_method(mrb, mrb->kernel_module, "rand", mrb_random_g_rand, MRB_ARGS_OPT(1)); 326 mrb_define_method(mrb, mrb->kernel_module, "srand", mrb_random_g_srand, MRB_ARGS_OPT(1)); 358 mrb_assert(sizeof(rand_state) <= ISTRUCT_DATA_SIZE); 359 360 mrb_define_method(mrb, mrb->kernel_module, "rand", random_f_rand, MRB_ARGS_OPT(1)); 361 mrb_define_method(mrb, mrb->kernel_module, "srand", random_f_srand, MRB_ARGS_OPT(1)); 327 362 328 363 random = mrb_define_class(mrb, "Random", mrb->object_class); 329 MRB_SET_INSTANCE_TT(random, MRB_TT_ DATA);330 mrb_define_class_method(mrb, random, "rand", mrb_random_g_rand, MRB_ARGS_OPT(1));331 mrb_define_class_method(mrb, random, "srand", mrb_random_g_srand, MRB_ARGS_OPT(1));332 333 mrb_define_method(mrb, random, "initialize", mrb_random_init, MRB_ARGS_OPT(1));334 mrb_define_method(mrb, random, "rand", mrb_random_rand, MRB_ARGS_OPT(1));335 mrb_define_method(mrb, random, "srand", mrb_random_srand, MRB_ARGS_OPT(1));364 MRB_SET_INSTANCE_TT(random, MRB_TT_ISTRUCT); 365 mrb_define_class_method(mrb, random, "rand", random_f_rand, MRB_ARGS_OPT(1)); 366 mrb_define_class_method(mrb, random, "srand", random_f_srand, MRB_ARGS_OPT(1)); 367 368 mrb_define_method(mrb, random, "initialize", random_m_init, MRB_ARGS_OPT(1)); 369 mrb_define_method(mrb, random, "rand", random_m_rand, MRB_ARGS_OPT(1)); 370 mrb_define_method(mrb, random, "srand", random_m_srand, MRB_ARGS_OPT(1)); 336 371 337 372 mrb_define_method(mrb, array, "shuffle", mrb_ary_shuffle, MRB_ARGS_OPT(1)); -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-random/test/random.rb
r331 r439 2 2 # Random Test 3 3 4 assert("Random #srand") do4 assert("Random.new") do 5 5 r1 = Random.new(123) 6 6 r2 = Random.new(123) 7 r1.rand == r2.rand 7 r3 = Random.new(124) 8 assert_equal(r1.rand, r2.rand) 9 assert_not_equal(r1.rand, r3.rand) 8 10 end 9 11 10 assert("Kernel ::srand") do12 assert("Kernel.srand") do 11 13 srand(234) 12 14 r1 = rand 13 15 srand(234) 14 16 r2 = rand 15 r1 == r2 17 srand(235) 18 r3 = rand 19 assert_equal(r1, r2) 20 assert_not_equal(r1, r3) 16 21 end 17 22 18 assert("Random ::srand") do23 assert("Random.srand") do 19 24 Random.srand(345) 20 25 r1 = rand 21 26 srand(345) 22 27 r2 = Random.rand 23 r1 == r2 28 Random.srand(346) 29 r3 = rand 30 assert_equal(r1, r2) 31 assert_not_equal(r1, r3) 24 32 end 25 33 26 assert("fixnum") do 27 rand(3).class == Fixnum 28 end 29 30 assert("float") do 31 rand.class == Float 34 assert("return class of Kernel.rand") do 35 assert_kind_of(Fixnum, rand(3)) 36 assert_kind_of(Fixnum, rand(1.5)) 37 assert_kind_of(Float, rand) 38 assert_kind_of(Float, rand(0.5)) 32 39 end 33 40 34 41 assert("Array#shuffle") do 35 ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 42 orig = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 43 ary = orig.dup 36 44 shuffled = ary.shuffle 37 38 ary == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and shuffled != ary and 10.times { |x| ary.include? x } 45 assert_equal(orig, ary) 46 assert_not_equal(ary, shuffled) 47 assert_equal(orig, shuffled.sort) 39 48 end 40 49 41 50 assert('Array#shuffle!') do 42 ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 43 ary.shuffle! 44 45 ary != [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and 10.times { |x| ary.include? x } 51 orig = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 52 ary = orig.dup 53 assert_same(ary, ary.shuffle!) 54 assert_not_equal(orig, ary) 55 assert_equal(orig, ary.sort) 46 56 end 47 57 … … 53 63 54 64 # verify that the same seed causes the same results 55 ary 1= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]56 shuffle 1 = ary1.shuffle Random.new 34557 ary2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]58 shuffle 2 = ary2.shuffle Random.new 34559 60 a ry1 != shuffle1 and 10.times { |x| shuffle1.include? x } and shuffle1 == shuffle265 ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 66 shuffled1 = ary.shuffle Random.new 345 67 shuffled2 = ary.shuffle Random.new 345 68 shuffled3 = ary.shuffle Random.new 346 69 assert_equal(shuffled1, shuffled2) 70 assert_not_equal(shuffled1, shuffled3) 61 71 end 62 72 … … 72 82 ary2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 73 83 ary2.shuffle! Random.new 345 74 75 ary1 != [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and 10.times { |x| ary1.include? x } and ary1 == ary2 84 ary3 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 85 ary3.shuffle! Random.new 346 86 assert_equal(ary1, ary2) 87 assert_not_equal(ary1, ary3) 76 88 end 77 89 78 assert('Array#sample checks input length after reading arguments') do 79 $ary = [1, 2, 3] 80 class ArrayChange 81 def to_i 82 $ary << 4 83 4 90 assert('Array#sample') do 91 100.times do 92 assert_include([0, 1, 2], [2, 1, 0].sample) 93 [2, 1, 0].sample(2).each { |sample| assert_include([0, 1, 2], sample) } 94 h = {} 95 (1..10).to_a.sample(7).each do |sample| 96 assert_not_include(h, sample) 97 h[sample] = true 84 98 end 85 99 end 86 100 87 assert_equal [1, 2, 3, 4], $ary.sample(ArrayChange.new).sort 101 assert_nil([].sample) 102 assert_equal([], [].sample(1)) 103 assert_equal([], [2, 1].sample(0)) 104 assert_raise(TypeError) { [2, 1].sample(true) } 105 assert_raise(ArgumentError) { [2, 1].sample(-1) } 88 106 end 107 108 assert('Array#sample(random)') do 109 assert_raise(TypeError) do 110 # this will cause an exception due to the wrong argument 111 [1, 2].sample(2, "Not a Random instance") 112 end 113 114 # verify that the same seed causes the same results 115 ary = (1..10).to_a 116 srand(15) 117 samples1 = ary.sample(4) 118 samples2 = ary.sample(4, Random.new(15)) 119 samples3 = ary.sample(4, Random.new(16)) 120 assert_equal(samples1, samples2) 121 assert_not_equal(samples1, samples3) 122 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-range-ext/mrblib/range.rb
r331 r439 16 16 raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 1)" unless args.length == 1 17 17 nv = args[0] 18 raise TypeError, "no implicit conversion from nil to integer" if nv.nil? 19 raise TypeError, "no implicit conversion of #{nv.class} into Integer" unless nv.respond_to?(:to_int) 20 n = nv.to_int 21 raise TypeError, "no implicit conversion of #{nv.class} into Integer" unless n.kind_of?(Integer) 18 n = nv.__to_int 22 19 raise ArgumentError, "negative array size (or size too big)" unless 0 <= n 23 20 ary = [] … … 29 26 ary 30 27 end 28 29 def max(&block) 30 val = self.first 31 last = self.last 32 return super if block 33 34 # fast path for numerics 35 if val.kind_of?(Numeric) && last.kind_of?(Numeric) 36 raise TypeError if exclude_end? && !last.kind_of?(Fixnum) 37 return nil if val > last 38 return nil if val == last && exclude_end? 39 40 max = last 41 max -= 1 if exclude_end? 42 return max 43 end 44 45 # delegate to Enumerable 46 super 47 end 48 49 def min(&block) 50 val = self.first 51 last = self.last 52 return super if block 53 54 # fast path for numerics 55 if val.kind_of?(Numeric) && last.kind_of?(Numeric) 56 return nil if val > last 57 return nil if val == last && exclude_end? 58 59 min = val 60 return min 61 end 62 63 # delegate to Enumerable 64 super 65 end 31 66 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-range-ext/src/range.c
r331 r439 2 2 #include <mruby/range.h> 3 3 #include <math.h> 4 #include <float.h>5 4 6 5 static mrb_bool 7 6 r_le(mrb_state *mrb, mrb_value a, mrb_value b) 8 7 { 9 mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */ 10 /* output :a < b => -1, a = b => 0, a > b => +1 */ 8 mrb_int n = mrb_cmp(mrb, a, b); 11 9 12 if (mrb_fixnum_p(r)) { 13 mrb_int c = mrb_fixnum(r); 14 if (c == 0 || c == -1) return TRUE; 15 } 16 10 if (n == 0 || n == -1) return TRUE; 17 11 return FALSE; 18 12 } … … 21 15 r_lt(mrb_state *mrb, mrb_value a, mrb_value b) 22 16 { 23 mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); 24 /* output :a < b => -1, a = b => 0, a > b => +1 */ 25 26 return mrb_fixnum_p(r) && mrb_fixnum(r) == -1; 17 return mrb_cmp(mrb, a, b) == -1; 27 18 } 28 19 … … 42 33 */ 43 34 static mrb_value 44 mrb_range_cover(mrb_state *mrb, mrb_value range)35 range_cover(mrb_state *mrb, mrb_value range) 45 36 { 46 37 mrb_value val; … … 50 41 mrb_get_args(mrb, "o", &val); 51 42 52 beg = r->edges->beg;53 end = r->edges->end;43 beg = RANGE_BEG(r); 44 end = RANGE_END(r); 54 45 55 46 if (r_le(mrb, beg, val)) { 56 if ( r->excl) {47 if (RANGE_EXCL(r)) { 57 48 if (r_lt(mrb, val, end)) 58 49 return mrb_true_value(); … … 84 75 */ 85 76 static mrb_value 86 mrb_range_last(mrb_state *mrb, mrb_value range)77 range_last(mrb_state *mrb, mrb_value range) 87 78 { 88 79 mrb_value num; 89 80 mrb_value array; 90 struct RRange *r = mrb_range_ptr(mrb, range);91 81 92 82 if (mrb_get_args(mrb, "|o", &num) == 0) { 93 return r->edges->end;83 return mrb_range_end(mrb, range); 94 84 } 95 85 … … 109 99 */ 110 100 101 #ifndef MRB_WITHOUT_FLOAT 111 102 static mrb_value 112 mrb_range_size(mrb_state *mrb, mrb_value range)103 range_size(mrb_state *mrb, mrb_value range) 113 104 { 114 105 struct RRange *r = mrb_range_ptr(mrb, range); … … 118 109 mrb_bool excl; 119 110 120 beg = r->edges->beg;121 end = r->edges->end;122 excl = r->excl;111 beg = RANGE_BEG(r); 112 end = RANGE_END(r); 113 excl = RANGE_EXCL(r); 123 114 if (mrb_fixnum_p(beg)) { 124 115 beg_f = (mrb_float)mrb_fixnum(beg); … … 161 152 return mrb_nil_value(); 162 153 } 154 #else 155 static mrb_value 156 range_size(mrb_state *mrb, mrb_value range) 157 { 158 struct RRange *r = mrb_range_ptr(mrb, range); 159 mrb_value beg, end; 160 mrb_int excl; 161 162 beg = RANGE_BEG(r); 163 end = RANGE_END(r); 164 excl = RANGE_EXCL(r) ? 0 : 1; 165 166 if (mrb_fixnum_p(beg) && mrb_fixnum_p(end)) { 167 mrb_int a = mrb_fixnum(beg); 168 mrb_int b = mrb_fixnum(end); 169 mrb_int c = b - a + excl; 170 171 return mrb_fixnum_value(c); 172 } 173 return mrb_nil_value(); 174 } 175 #endif /* MRB_WITHOUT_FLOAT */ 163 176 164 177 void … … 167 180 struct RClass * s = mrb_class_get(mrb, "Range"); 168 181 169 mrb_define_method(mrb, s, "cover?", mrb_range_cover, MRB_ARGS_REQ(1));170 mrb_define_method(mrb, s, "last", mrb_range_last, MRB_ARGS_OPT(1));171 mrb_define_method(mrb, s, "size", mrb_range_size, MRB_ARGS_NONE());182 mrb_define_method(mrb, s, "cover?", range_cover, MRB_ARGS_REQ(1)); 183 mrb_define_method(mrb, s, "last", range_last, MRB_ARGS_OPT(1)); 184 mrb_define_method(mrb, s, "size", range_size, MRB_ARGS_NONE()); 172 185 } 173 186 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-range-ext/test/range.rb
r331 r439 11 11 assert_equal 10, (10..20).first 12 12 assert_equal [10, 11, 12], (10..20).first(3) 13 14 skip unless Object.const_defined?(:Float) 13 15 assert_equal [0, 1, 2], (0..Float::INFINITY).first(3) 14 16 end … … 24 26 assert_equal 42, (1..42).size 25 27 assert_equal 41, (1...42).size 28 assert_nil ('a'..'z').size 29 30 skip unless Object.const_defined?(:Float) 26 31 assert_equal 6, (1...6.3).size 27 32 assert_equal 5, (1...6.0).size … … 29 34 assert_equal 15, (1.0..15.9).size 30 35 assert_equal Float::INFINITY, (0..Float::INFINITY).size 31 assert_nil ('a'..'z').size32 36 end 37 38 assert('Range#max') do 39 # returns the maximum value in the range when called with no arguments 40 assert_equal 10, (1..10).max 41 assert_equal 9, (1...10).max 42 assert_equal 536870911, (0...2**29).max 43 44 # returns nil when the endpoint is less than the start point 45 assert_equal nil, (100..10).max 46 47 # returns nil when the endpoint equals the start point and the range is exclusive 48 assert_equal nil, (5...5).max 49 50 # returns the endpoint when the endpoint equals the start point and the range is inclusive 51 assert_equal 5, (5..5).max 52 53 skip unless Object.const_defined?(:Float) 54 55 # returns the maximum value in the Float range when called with no arguments 56 assert_equal 908.1111, (303.20..908.1111).max 57 58 # raises TypeError when called on an exclusive range and a non Integer value 59 assert_raise(TypeError) { (303.20...908.1111).max } 60 61 # returns nil when the endpoint is less than the start point in a Float range 62 assert_equal nil, (3003.20..908.1111).max 63 end 64 65 assert('Range#max given a block') do 66 # passes each pair of values in the range to the block 67 acc = [] 68 (1..10).max do |a, b| 69 acc << a 70 acc << b 71 a 72 end 73 (1..10).each do |value| 74 assert_true acc.include?(value) 75 end 76 77 # passes each pair of elements to the block in reversed order 78 acc = [] 79 (1..5).max do |a, b| 80 acc << [a, b] 81 a 82 end 83 assert_equal [[2, 1], [3, 2], [4, 3], [5, 4]], acc 84 85 # returns the element the block determines to be the maximum 86 assert_equal 1, ((1..3).max { |_a, _b| -3 }) 87 88 # returns nil when the endpoint is less than the start point 89 assert_equal nil, ((100..10).max { |x, y| x <=> y }) 90 assert_equal nil, ((5...5).max { |x, y| x <=> y }) 91 end 92 93 assert('Range#min') do 94 # returns the minimum value in the range when called with no arguments 95 assert_equal 1, (1..10).min 96 assert_equal 1, (1...10).min 97 98 # returns nil when the start point is greater than the endpoint 99 assert_equal nil, (100..10).min 100 101 # returns nil when the endpoint equals the start point and the range is exclusive 102 assert_equal nil, (5...5).max 103 104 # returns the endpoint when the endpoint equals the start point and the range is inclusive 105 assert_equal 5, (5..5).max 106 107 skip unless Object.const_defined?(:Float) 108 109 # returns the minimum value in the Float range when called with no arguments 110 assert_equal 303.20, (303.20..908.1111).min 111 112 # returns nil when the start point is greater than the endpoint in a Float range 113 assert_equal nil, (3003.20..908.1111).max 114 end 115 116 assert('Range#min given a block') do 117 # passes each pair of values in the range to the block 118 acc = [] 119 (1..10).min do |a, b| 120 acc << a 121 acc << b 122 a 123 end 124 (1..10).each do |value| 125 assert_true acc.include?(value) 126 end 127 128 # passes each pair of elements to the block in reversed order 129 acc = [] 130 (1..5).min do |a, b| 131 acc << [a, b] 132 a 133 end 134 assert_equal [[2, 1], [3, 1], [4, 1], [5, 1]], acc 135 136 # returns the element the block determines to be the minimum 137 assert_equal 3, ((1..3).min { |_a, _b| -3 }) 138 139 # returns nil when the start point is greater than the endpoint 140 assert_equal nil, ((100..10).min { |x, y| x <=> y }) 141 assert_equal nil, ((5...5).min { |x, y| x <=> y }) 142 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-sprintf/src/kernel.c
r331 r439 19 19 krn = mrb->kernel_module; 20 20 21 mrb_define_method(mrb, krn, "sprintf", mrb_f_sprintf, MRB_ARGS_ ANY());22 mrb_define_method(mrb, krn, "format", mrb_f_sprintf, MRB_ARGS_ ANY());21 mrb_define_method(mrb, krn, "sprintf", mrb_f_sprintf, MRB_ARGS_REQ(1)|MRB_ARGS_REST()); 22 mrb_define_method(mrb, krn, "format", mrb_f_sprintf, MRB_ARGS_REQ(1)|MRB_ARGS_REST()); 23 23 } 24 24 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-sprintf/src/sprintf.c
r331 r439 7 7 #include <mruby.h> 8 8 9 #ifdef MRB_DISABLE_STDIO 10 # error sprintf conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb' 11 #endif 12 9 13 #include <limits.h> 10 #include <stdio.h>11 14 #include <string.h> 12 15 #include <mruby/string.h> 13 16 #include <mruby/hash.h> 14 17 #include <mruby/numeric.h> 18 #ifndef MRB_WITHOUT_FLOAT 15 19 #include <math.h> 20 #endif 16 21 #include <ctype.h> 17 22 … … 20 25 #define EXTENDSIGN(n, l) (((~0U << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0U << (n))) 21 26 22 mrb_value mrb_str_format(mrb_state *, int, const mrb_value *, mrb_value); 27 mrb_value mrb_str_format(mrb_state *, mrb_int, const mrb_value *, mrb_value); 28 #ifndef MRB_WITHOUT_FLOAT 23 29 static void fmt_setup(char*,size_t,int,int,mrb_int,mrb_int); 30 #endif 24 31 25 32 static char* … … 78 85 79 86 if (base != 2) { 80 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix % S", mrb_fixnum_value(base));87 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %d", base); 81 88 } 82 89 if (val == 0) { … … 116 123 117 124 #define CHECK(l) do {\ 118 /* int cr = ENC_CODERANGE(result);*/\119 125 while ((l) >= bsiz - blen) {\ 126 if (bsiz > MRB_INT_MAX/2) mrb_raise(mrb, E_ARGUMENT_ERROR, "too big specifier"); \ 120 127 bsiz*=2;\ 121 if (bsiz < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "too big specifier"); \122 128 }\ 123 129 mrb_str_resize(mrb, result, bsiz);\ 124 /* ENC_CODERANGE_SET(result, cr);*/\125 130 buf = RSTRING_PTR(result);\ 126 131 } while (0) … … 129 134 CHECK(l);\ 130 135 memcpy(&buf[blen], s, l);\ 131 blen += ( l);\136 blen += (mrb_int)(l);\ 132 137 } while (0) 133 138 … … 143 148 switch (posarg) { 144 149 case -1: 145 mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(% S) mixed with numbered", mrb_fixnum_value(nextarg));150 mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%d) mixed with numbered", nextarg); 146 151 break; 147 152 case -2: 148 mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(% S) mixed with named", mrb_fixnum_value(nextarg));153 mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%d) mixed with named", nextarg); 149 154 break; 150 155 default: … … 154 159 155 160 static void 156 check_pos_arg(mrb_state *mrb, int posarg, int n)161 check_pos_arg(mrb_state *mrb, int posarg, mrb_int n) 157 162 { 158 163 if (posarg > 0) { 159 mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(% S) after unnumbered(%S)",160 mrb_fixnum_value(n), mrb_fixnum_value(posarg));164 mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%i) after unnumbered(%d)", 165 n, posarg); 161 166 } 162 167 if (posarg == -2) { 163 mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(% S) after named", mrb_fixnum_value(n));168 mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%i) after named", n); 164 169 } 165 170 if (n < 1) { 166 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - % S$", mrb_fixnum_value(n));171 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - %i$", n); 167 172 } 168 173 } 169 174 170 175 static void 171 check_name_arg(mrb_state *mrb, int posarg, const char *name, int len)176 check_name_arg(mrb_state *mrb, int posarg, const char *name, size_t len) 172 177 { 173 178 if (posarg > 0) { 174 mrb_raisef(mrb, E_ARGUMENT_ERROR, "named% S after unnumbered(%S)",175 mrb_str_new(mrb, (name), (len)), mrb_fixnum_value(posarg));179 mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%l after unnumbered(%d)", 180 name, len, posarg); 176 181 } 177 182 if (posarg == -1) { 178 mrb_raisef(mrb, E_ARGUMENT_ERROR, "named% S after numbered", mrb_str_new(mrb, (name), (len)));183 mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%l after numbered", name, len); 179 184 } 180 185 } … … 199 204 #define GETNUM(n, val) \ 200 205 for (; p < end && ISDIGIT(*p); p++) {\ 201 int next_n = 10 * n + (*p - '0'); \ 202 if (next_n / 10 != n) {\ 206 if (n > (MRB_INT_MAX - (*p - '0'))/10) {\ 203 207 mrb_raise(mrb, E_ARGUMENT_ERROR, #val " too big"); \ 204 208 } \ 205 n = next_n; \209 n = 10 * n + (*p - '0'); \ 206 210 } \ 207 211 if (p >= end) { \ … … 225 229 226 230 static mrb_value 227 get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv)231 get_hash(mrb_state *mrb, mrb_value *hash, mrb_int argc, const mrb_value *argv) 228 232 { 229 233 mrb_value tmp; … … 233 237 mrb_raise(mrb, E_ARGUMENT_ERROR, "one hash required"); 234 238 } 235 tmp = mrb_check_ convert_type(mrb, argv[1], MRB_TT_HASH, "Hash", "to_hash");239 tmp = mrb_check_hash_type(mrb, argv[1]); 236 240 if (mrb_nil_p(tmp)) { 237 241 mrb_raise(mrb, E_ARGUMENT_ERROR, "one hash required"); … … 519 523 520 524 mrb_value 521 mrb_str_format(mrb_state *mrb, int argc, const mrb_value *argv, mrb_value fmt)525 mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fmt) 522 526 { 523 527 const char *p, *end; … … 529 533 mrb_int width; 530 534 mrb_int prec; 531 int flags = FNONE;532 535 int nextarg = 1; 533 536 int posarg = 0; … … 553 556 ++argc; 554 557 --argv; 555 fmt = mrb_str_to_str(mrb, fmt);558 mrb_to_str(mrb, fmt); 556 559 p = RSTRING_PTR(fmt); 557 560 end = p + RSTRING_LEN(fmt); 558 561 blen = 0; 559 562 bsiz = 120; 560 result = mrb_str_ buf_new(mrb, bsiz);563 result = mrb_str_new_capa(mrb, bsiz); 561 564 buf = RSTRING_PTR(result); 562 565 memset(buf, 0, bsiz); … … 565 568 const char *t; 566 569 mrb_sym id = 0; 570 int flags = FNONE; 567 571 568 572 for (t = p; t < end && *t != '%'; t++) ; … … 580 584 switch (*p) { 581 585 default: 582 mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed format string - \\%%S", mrb_str_new(mrb, p, 1));586 mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed format string - %%%c", *p); 583 587 break; 584 588 … … 619 623 if (*p == '$') { 620 624 if (!mrb_undef_p(nextvalue)) { 621 mrb_raisef(mrb, E_ARGUMENT_ERROR, "value given twice - % S$", mrb_fixnum_value(n));625 mrb_raisef(mrb, E_ARGUMENT_ERROR, "value given twice - %i$", n); 622 626 } 623 627 nextvalue = GETPOSARG(n); … … 639 643 p++; 640 644 if (id) { 641 mrb_raisef(mrb, E_ARGUMENT_ERROR, "name% S after <%S>",642 mrb_str_new(mrb, start, p - start + 1), mrb_sym2str(mrb, id));645 mrb_raisef(mrb, E_ARGUMENT_ERROR, "name%l after <%n>", 646 start, p - start + 1, id); 643 647 } 644 648 symname = mrb_str_new(mrb, start + 1, p - start - 1); 645 649 id = mrb_intern_str(mrb, symname); 646 nextvalue = GETNAMEARG(mrb_symbol_value(id), start, (int)(p - start + 1));650 nextvalue = GETNAMEARG(mrb_symbol_value(id), start, p - start + 1); 647 651 if (mrb_undef_p(nextvalue)) { 648 mrb_raisef(mrb, E_KEY_ERROR, "key% S not found", mrb_str_new(mrb, start, p - start + 1));652 mrb_raisef(mrb, E_KEY_ERROR, "key%l not found", start, p - start + 1); 649 653 } 650 654 if (term == '}') goto format_s; … … 702 706 tmp = mrb_check_string_type(mrb, val); 703 707 if (!mrb_nil_p(tmp)) { 704 if ( mrb_fixnum(mrb_funcall(mrb, tmp, "size", 0)) != 1) {708 if (RSTRING_LEN(tmp) != 1) { 705 709 mrb_raise(mrb, E_ARGUMENT_ERROR, "%c requires a character"); 706 710 } 707 711 } 708 712 else if (mrb_fixnum_p(val)) { 709 tmp = mrb_funcall(mrb, val, "chr", 0); 713 mrb_int n = mrb_fixnum(val); 714 715 if (n < 0x80) { 716 char buf[1]; 717 718 buf[0] = (char)n; 719 tmp = mrb_str_new(mrb, buf, 1); 720 } 721 else { 722 tmp = mrb_funcall(mrb, val, "chr", 0); 723 mrb_check_type(mrb, tmp, MRB_TT_STRING); 724 } 710 725 } 711 726 else { 712 727 mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid character"); 713 728 } 714 mrb_check_type(mrb, tmp, MRB_TT_STRING);715 729 c = RSTRING_PTR(tmp); 716 730 n = RSTRING_LEN(tmp); … … 756 770 char *p = RSTRING_PTR(str) + prec; 757 771 slen = prec; 758 len = p - RSTRING_PTR(str);772 len = (mrb_int)(p - RSTRING_PTR(str)); 759 773 } 760 774 /* need to adjust multi-byte string pos */ … … 792 806 mrb_int len; 793 807 794 switch (*p) {795 case 'd':796 case 'i':797 sign = 1; break;798 default:799 break;800 }801 808 if (flags & FSHARP) { 802 809 switch (*p) { … … 812 819 bin_retry: 813 820 switch (mrb_type(val)) { 821 #ifndef MRB_WITHOUT_FLOAT 814 822 case MRB_TT_FLOAT: 815 823 val = mrb_flo_to_fixnum(mrb, val); 816 824 if (mrb_fixnum_p(val)) goto bin_retry; 817 825 break; 826 #endif 818 827 case MRB_TT_STRING: 819 828 val = mrb_str_to_inum(mrb, val, 0, TRUE); … … 839 848 case 'd': 840 849 case 'i': 850 sign = 1; 851 /* fall through */ 841 852 default: 842 853 base = 10; break; 843 854 } 844 855 845 if (base == 2) {846 if (v < 0 && !sign) {847 val = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base);848 dots = 1;849 }850 else {851 val = mrb_fixnum_to_str(mrb, mrb_fixnum_value(v), base);852 }853 }854 856 if (sign) { 855 if (v > 0) {857 if (v >= 0) { 856 858 if (flags & FPLUS) { 857 859 sc = '+'; … … 863 865 } 864 866 } 867 else { 868 sc = '-'; 869 width--; 870 } 871 mrb_assert(base == 10); 872 snprintf(nbuf, sizeof(nbuf), "%" MRB_PRId, v); 873 s = nbuf; 874 if (v < 0) s++; /* skip minus sign */ 875 } 876 else { 877 s = nbuf; 878 if (v < 0) { 879 dots = 1; 880 } 865 881 switch (base) { 866 882 case 2: 867 strncpy(nbuf, RSTRING_PTR(val), sizeof(nbuf)); 868 break; 869 case 8: 870 snprintf(nbuf, sizeof(nbuf), "%" MRB_PRIo, v); 871 break; 872 case 10: 873 snprintf(nbuf, sizeof(nbuf), "%" MRB_PRId, v); 874 break; 875 case 16: 876 snprintf(nbuf, sizeof(nbuf), "%" MRB_PRIx, v); 877 break; 878 } 879 s = nbuf; 880 } 881 else { 882 s = nbuf; 883 if (base != 10 && v < 0) { 884 dots = 1; 885 } 886 switch (base) { 887 case 2: 883 if (v < 0) { 884 val = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base); 885 } 886 else { 887 val = mrb_fixnum_to_str(mrb, mrb_fixnum_value(v), base); 888 } 888 889 strncpy(++s, RSTRING_PTR(val), sizeof(nbuf)-1); 889 890 break; 890 891 case 8: 891 892 snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRIo, v); 892 break;893 case 10:894 snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRId, v);895 893 break; 896 894 case 16: … … 921 919 } 922 920 923 if (dots) {924 prec -= 2;925 width -= 2;926 }927 928 921 if (*p == 'X') { 929 922 char *pp = s; … … 973 966 if (!(flags&FMINUS) && width > 0) { 974 967 FILL(' ', width); 968 width = 0; 975 969 } 976 970 … … 981 975 PUSH(prefix, plen); 982 976 } 983 if (dots) PUSH("..", 2); 977 if (dots) { 978 prec -= 2; 979 width -= 2; 980 PUSH("..", 2); 981 } 984 982 985 983 if (prec > len) { 986 984 CHECK(prec - len); 987 if (v < 0) { 985 if ((flags & (FMINUS|FPREC)) != FMINUS) { 986 char c = '0'; 987 FILL(c, prec - len); 988 } else if (v < 0) { 988 989 char c = sign_bits(base, p); 989 FILL(c, prec - len);990 }991 else if ((flags & (FMINUS|FPREC)) != FMINUS) {992 char c = '0';993 990 FILL(c, prec - len); 994 991 } … … 1001 998 break; 1002 999 1000 #ifndef MRB_WITHOUT_FLOAT 1003 1001 case 'f': 1004 1002 case 'g': … … 1010 1008 mrb_value val = GETARG(); 1011 1009 double fval; 1012 int i,need = 6;1010 mrb_int need = 6; 1013 1011 char fbuf[32]; 1014 1012 … … 1016 1014 if (!isfinite(fval)) { 1017 1015 const char *expr; 1018 const int elen = 3;1016 const mrb_int elen = 3; 1019 1017 char sign = '\0'; 1020 1018 … … 1031 1029 sign = (flags & FPLUS) ? '+' : ' '; 1032 1030 if (sign) 1033 1031 ++need; 1034 1032 if ((flags & FWIDTH) && need < width) 1035 1033 need = width; … … 1055 1053 need = 0; 1056 1054 if (*p != 'e' && *p != 'E') { 1057 i = INT_MIN;1055 int i; 1058 1056 frexp(fval, &i); 1059 1057 if (i > 0) 1060 1058 need = BIT_DIGITS(i); 1061 1059 } 1060 if (need > MRB_INT_MAX - ((flags&FPREC) ? prec : 6)) { 1061 too_big_width: 1062 mrb_raise(mrb, E_ARGUMENT_ERROR, 1063 (width > prec ? "width too big" : "prec too big")); 1064 } 1062 1065 need += (flags&FPREC) ? prec : 6; 1063 1066 if ((flags&FWIDTH) && need < width) 1064 1067 need = width; 1068 if (need > MRB_INT_MAX - 20) { 1069 goto too_big_width; 1070 } 1065 1071 need += 20; 1066 if (need <= 0) {1067 mrb_raise(mrb, E_ARGUMENT_ERROR,1068 (width > prec ? "width too big" : "prec too big"));1069 }1070 1072 1071 1073 CHECK(need); 1072 1074 n = snprintf(&buf[blen], need, fbuf, fval); 1073 if (n < 0 ) {1075 if (n < 0 || n >= need) { 1074 1076 mrb_raise(mrb, E_RUNTIME_ERROR, "formatting error"); 1075 1077 } … … 1077 1079 } 1078 1080 break; 1081 #endif 1079 1082 } 1080 1083 flags = FNONE; … … 1088 1091 const char *mesg = "too many arguments for format string"; 1089 1092 if (mrb_test(ruby_debug)) mrb_raise(mrb, E_ARGUMENT_ERROR, mesg); 1090 if (mrb_test(ruby_verbose)) mrb_warn(mrb, "% S", mrb_str_new_cstr(mrb, mesg));1093 if (mrb_test(ruby_verbose)) mrb_warn(mrb, "%s", mesg); 1091 1094 } 1092 1095 #endif … … 1096 1099 } 1097 1100 1101 #ifndef MRB_WITHOUT_FLOAT 1098 1102 static void 1099 1103 fmt_setup(char *buf, size_t size, int c, int flags, mrb_int width, mrb_int prec) … … 1122 1126 *buf = '\0'; 1123 1127 } 1128 #endif -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-sprintf/test/sprintf.rb
r331 r439 4 4 assert('String#%') do 5 5 assert_equal "one=1", "one=%d" % 1 6 assert_equal "1 one 1.0", "%d %s %3.1f" % [ 1, "one", 1.01]6 assert_equal "1 one", "%d %s" % [ 1, "one" ] 7 7 assert_equal "123 < 456", "%{num} < %<str>s" % { num: 123, str: "456" } 8 8 assert_equal 15, ("%b" % (1<<14)).size 9 skip unless Object.const_defined?(:Float) 10 assert_equal "1.0", "%3.1f" % 1.01 9 11 end 10 12 11 13 assert('String#% with inf') do 14 skip unless Object.const_defined?(:Float) 12 15 inf = Float::INFINITY 13 16 … … 38 41 39 42 assert('String#% with nan') do 43 skip unless Object.const_defined?(:Float) 40 44 nan = Float::NAN 41 45 … … 76 80 77 81 assert_raise TypeError do 78 "%c" % 0 82 "%c" % 0x80 79 83 end 80 84 ensure … … 92 96 end 93 97 98 assert("String#% %d") do 99 assert_equal(" 10", "%4d" % 10) 100 assert_equal("1000", "%4d" % 1000) 101 assert_equal("10000", "%4d" % 10000) 102 end 103 94 104 assert("String#% invalid format") do 95 105 assert_raise ArgumentError do -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-string-ext/mrbgem.rake
r331 r439 3 3 spec.author = 'mruby developers' 4 4 spec.summary = 'String class extension' 5 spec.add_test_dependency 'mruby-enumerator', core: 'mruby-enumerator'6 5 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-string-ext/mrblib/string.rb
r331 r439 1 1 class String 2 3 ##4 # call-seq:5 # String.try_convert(obj) -> string or nil6 #7 # Try to convert <i>obj</i> into a String, using to_str method.8 # Returns converted string or nil if <i>obj</i> cannot be converted9 # for any reason.10 #11 # String.try_convert("str") #=> "str"12 # String.try_convert(/re/) #=> nil13 #14 def self.try_convert(obj)15 if obj.respond_to?(:to_str)16 obj.to_str17 else18 nil19 end20 end21 2 22 3 ## … … 96 77 # 97 78 def lstrip! 98 raise RuntimeError, "can't modify frozen String" if frozen?79 raise FrozenError, "can't modify frozen String" if frozen? 99 80 s = self.lstrip 100 81 (s == self) ? nil : self.replace(s) … … 113 94 # 114 95 def rstrip! 115 raise RuntimeError, "can't modify frozen String" if frozen?96 raise FrozenError, "can't modify frozen String" if frozen? 116 97 s = self.rstrip 117 98 (s == self) ? nil : self.replace(s) … … 126 107 # 127 108 def strip! 128 raise RuntimeError, "can't modify frozen String" if frozen?109 raise FrozenError, "can't modify frozen String" if frozen? 129 110 s = self.strip 130 111 (s == self) ? nil : self.replace(s) … … 143 124 # 144 125 def casecmp(str) 145 self.downcase <=> str. to_str.downcase126 self.downcase <=> str.__to_str.downcase 146 127 rescue NoMethodError 147 raise TypeError, "no implicit conversion of #{str.class} into String" 128 nil 129 end 130 131 ## 132 # call-seq: 133 # str.casecmp?(other) -> true, false, or nil 134 # 135 # Returns true if str and other_str are equal after case folding, 136 # false if they are not equal, and nil if other_str is not a string. 137 138 def casecmp?(str) 139 c = self.casecmp(str) 140 return nil if c.nil? 141 return c == 0 148 142 end 149 143 … … 187 181 # 188 182 def slice!(arg1, arg2=nil) 189 raise RuntimeError, "can't modify frozen String" if frozen?183 raise FrozenError, "can't modify frozen String" if frozen? 190 184 raise "wrong number of arguments (for 1..2)" if arg1.nil? && arg2.nil? 191 185 … … 317 311 end 318 312 313 ## 314 # Call the given block for each character of 315 # +self+. 319 316 def each_char(&block) 320 317 return to_enum :each_char unless block 321 322 split('').each do |i| 323 block.call(i) 318 pos = 0 319 while pos < self.size 320 block.call(self[pos]) 321 pos += 1 324 322 end 325 323 self … … 353 351 self 354 352 end 353 354 ## 355 # call-seq: 356 # string.lines -> array of string 357 # string.lines {|s| block} -> array of string 358 # 359 # Returns strings per line; 360 # 361 # a = "abc\ndef" 362 # a.lines #=> ["abc\n", "def"] 363 # 364 # If a block is given, it works the same as <code>each_line</code>. 365 def lines(&blk) 366 lines = self.__lines 367 if blk 368 lines.each do |line| 369 blk.call(line) 370 end 371 end 372 lines 373 end 374 375 ## 376 # call-seq: 377 # str.upto(other_str, exclusive=false) {|s| block } -> str 378 # str.upto(other_str, exclusive=false) -> an_enumerator 379 # 380 # Iterates through successive values, starting at <i>str</i> and 381 # ending at <i>other_str</i> inclusive, passing each value in turn to 382 # the block. The <code>String#succ</code> method is used to generate 383 # each value. If optional second argument exclusive is omitted or is false, 384 # the last value will be included; otherwise it will be excluded. 385 # 386 # If no block is given, an enumerator is returned instead. 387 # 388 # "a8".upto("b6") {|s| print s, ' ' } 389 # for s in "a8".."b6" 390 # print s, ' ' 391 # end 392 # 393 # <em>produces:</em> 394 # 395 # a8 a9 b0 b1 b2 b3 b4 b5 b6 396 # a8 a9 b0 b1 b2 b3 b4 b5 b6 397 # 398 # If <i>str</i> and <i>other_str</i> contains only ascii numeric characters, 399 # both are recognized as decimal numbers. In addition, the width of 400 # string (e.g. leading zeros) is handled appropriately. 401 # 402 # "9".upto("11").to_a #=> ["9", "10", "11"] 403 # "25".upto("5").to_a #=> [] 404 # "07".upto("11").to_a #=> ["07", "08", "09", "10", "11"] 405 def upto(max, exclusive=false, &block) 406 return to_enum(:upto, max, exclusive) unless block 407 raise TypeError, "no implicit conversion of #{max.class} into String" unless max.kind_of? String 408 409 len = self.length 410 maxlen = max.length 411 # single character 412 if len == 1 and maxlen == 1 413 c = self.ord 414 e = max.ord 415 while c <= e 416 break if exclusive and c == e 417 yield c.chr(__ENCODING__) 418 c += 1 419 end 420 return self 421 end 422 # both edges are all digits 423 bi = self.to_i(10) 424 ei = max.to_i(10) 425 len = self.length 426 if (bi > 0 or bi == "0"*len) and (ei > 0 or ei == "0"*maxlen) 427 while bi <= ei 428 break if exclusive and bi == ei 429 s = bi.to_s 430 s = s.rjust(len, "0") if s.length < len 431 yield s 432 bi += 1 433 end 434 return self 435 end 436 bs = self 437 while true 438 n = (bs <=> max) 439 break if n > 0 440 break if exclusive and n == 0 441 yield bs 442 break if n == 0 443 bs = bs.succ 444 end 445 self 446 end 355 447 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-string-ext/src/string.c
r331 r439 6 6 #include <mruby/range.h> 7 7 8 static mrb_value 9 mrb_str_getbyte(mrb_state *mrb, mrb_value str) 10 { 11 mrb_int pos; 12 mrb_get_args(mrb, "i", &pos); 13 14 if (pos < 0) 15 pos += RSTRING_LEN(str); 16 if (pos < 0 || RSTRING_LEN(str) <= pos) 17 return mrb_nil_value(); 18 19 return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[pos]); 20 } 21 22 static mrb_value 23 mrb_str_setbyte(mrb_state *mrb, mrb_value str) 24 { 25 mrb_int pos, byte; 26 long len; 27 28 mrb_get_args(mrb, "ii", &pos, &byte); 29 30 len = RSTRING_LEN(str); 31 if (pos < -len || len <= pos) 32 mrb_raisef(mrb, E_INDEX_ERROR, "index %S is out of array", mrb_fixnum_value(pos)); 33 if (pos < 0) 34 pos += len; 35 36 mrb_str_modify(mrb, mrb_str_ptr(str)); 37 byte &= 0xff; 38 RSTRING_PTR(str)[pos] = byte; 39 return mrb_fixnum_value((unsigned char)byte); 40 } 41 42 static mrb_value 43 mrb_str_byteslice(mrb_state *mrb, mrb_value str) 44 { 45 mrb_value a1; 8 #define ENC_ASCII_8BIT "ASCII-8BIT" 9 #define ENC_BINARY "BINARY" 10 #define ENC_UTF8 "UTF-8" 11 12 #define ENC_COMP_P(enc, enc_lit) \ 13 str_casecmp_p(RSTRING_PTR(enc), RSTRING_LEN(enc), enc_lit, sizeof(enc_lit"")-1) 14 15 #ifdef MRB_WITHOUT_FLOAT 16 # define mrb_float_p(o) FALSE 17 #endif 18 19 static mrb_bool 20 str_casecmp_p(const char *s1, mrb_int len1, const char *s2, mrb_int len2) 21 { 22 const char *e1, *e2; 23 24 if (len1 != len2) return FALSE; 25 e1 = s1 + len1; 26 e2 = s2 + len2; 27 while (s1 < e1 && s2 < e2) { 28 if (*s1 != *s2 && TOUPPER(*s1) != TOUPPER(*s2)) return FALSE; 29 ++s1; 30 ++s2; 31 } 32 return TRUE; 33 } 34 35 static mrb_value 36 int_chr_binary(mrb_state *mrb, mrb_value num) 37 { 38 mrb_int cp = mrb_int(mrb, num); 39 char c; 40 mrb_value str; 41 42 if (cp < 0 || 0xff < cp) { 43 mrb_raisef(mrb, E_RANGE_ERROR, "%v out of char range", num); 44 } 45 c = (char)cp; 46 str = mrb_str_new(mrb, &c, 1); 47 RSTR_SET_ASCII_FLAG(mrb_str_ptr(str)); 48 return str; 49 } 50 51 #ifdef MRB_UTF8_STRING 52 static mrb_value 53 int_chr_utf8(mrb_state *mrb, mrb_value num) 54 { 55 mrb_int cp = mrb_int(mrb, num); 56 char utf8[4]; 46 57 mrb_int len; 47 int argc;48 49 argc = mrb_get_args(mrb, "o|i", &a1, &len); 50 if ( argc == 2) {51 return mrb_str_substr(mrb, str, mrb_fixnum(a1), len);52 } 53 switch (mrb_type(a1)) {54 case MRB_TT_RANGE:55 {56 mrb_int beg;57 58 len = RSTRING_LEN(str);59 switch (mrb_range_beg_len(mrb, a1, &beg, &len, len, TRUE)) {60 case 0: /* not range */61 break;62 case 1: /* range */63 return mrb_str_substr(mrb, str, beg, len);64 case 2: /* out of range */65 mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", a1);66 break;67 }68 return mrb_nil_value();69 }70 case MRB_TT_FLOAT:71 a1 = mrb_fixnum_value((mrb_int)mrb_float(a1));72 /* fall through */73 case MRB_TT_FIXNUM:74 return mrb_str_substr(mrb, str, mrb_fixnum(a1), 1);75 default:76 mrb_raise(mrb, E_TYPE_ERROR, "wrong type of argument");77 }78 /* not reached */79 return mrb_nil_value(); 80 } 58 mrb_value str; 59 uint32_t ascii_flag = 0; 60 61 if (cp < 0 || 0x10FFFF < cp) { 62 mrb_raisef(mrb, E_RANGE_ERROR, "%v out of char range", num); 63 } 64 if (cp < 0x80) { 65 utf8[0] = (char)cp; 66 len = 1; 67 ascii_flag = MRB_STR_ASCII; 68 } 69 else if (cp < 0x800) { 70 utf8[0] = (char)(0xC0 | (cp >> 6)); 71 utf8[1] = (char)(0x80 | (cp & 0x3F)); 72 len = 2; 73 } 74 else if (cp < 0x10000) { 75 utf8[0] = (char)(0xE0 | (cp >> 12)); 76 utf8[1] = (char)(0x80 | ((cp >> 6) & 0x3F)); 77 utf8[2] = (char)(0x80 | ( cp & 0x3F)); 78 len = 3; 79 } 80 else { 81 utf8[0] = (char)(0xF0 | (cp >> 18)); 82 utf8[1] = (char)(0x80 | ((cp >> 12) & 0x3F)); 83 utf8[2] = (char)(0x80 | ((cp >> 6) & 0x3F)); 84 utf8[3] = (char)(0x80 | ( cp & 0x3F)); 85 len = 4; 86 } 87 str = mrb_str_new(mrb, utf8, len); 88 mrb_str_ptr(str)->flags |= ascii_flag; 89 return str; 90 } 91 #endif 81 92 82 93 /* … … 135 146 } 136 147 137 static mrb_value mrb_fixnum_chr(mrb_state *mrb, mrb_value num);138 139 148 /* 140 149 * call-seq: … … 146 155 * Append---Concatenates the given object to <i>str</i>. If the object is a 147 156 * <code>Integer</code>, it is considered as a codepoint, and is converted 148 * to a character before concatenation. 157 * to a character before concatenation 158 * (equivalent to <code>str.concat(integer.chr(__ENCODING__))</code>). 149 159 * 150 160 * a = "hello " … … 153 163 */ 154 164 static mrb_value 155 mrb_str_concat 2(mrb_state *mrb, mrb_value self)165 mrb_str_concat_m(mrb_state *mrb, mrb_value self) 156 166 { 157 167 mrb_value str; 158 168 159 169 mrb_get_args(mrb, "o", &str); 160 if (mrb_fixnum_p(str)) 161 str = mrb_fixnum_chr(mrb, str); 170 if (mrb_fixnum_p(str) || mrb_float_p(str)) 171 #ifdef MRB_UTF8_STRING 172 str = int_chr_utf8(mrb, str); 173 #else 174 str = int_chr_binary(mrb, str); 175 #endif 162 176 else 163 str = mrb_string_type(mrb, str);164 mrb_str_c oncat(mrb, self, str);177 mrb_ensure_string_type(mrb, str); 178 mrb_str_cat_str(mrb, self, str); 165 179 return self; 166 180 } … … 189 203 size_t len_l, len_r; 190 204 int ai = mrb_gc_arena_save(mrb); 191 sub = mrb_ string_type(mrb, argv[i]);205 sub = mrb_ensure_string_type(mrb, argv[i]); 192 206 mrb_gc_arena_restore(mrb, ai); 193 207 len_l = RSTRING_LEN(self); … … 218 232 size_t len_l, len_r; 219 233 int ai = mrb_gc_arena_save(mrb); 220 sub = mrb_ string_type(mrb, argv[i]);234 sub = mrb_ensure_string_type(mrb, argv[i]); 221 235 mrb_gc_arena_restore(mrb, ai); 222 236 len_l = RSTRING_LEN(self); … … 233 247 } 234 248 249 enum tr_pattern_type { 250 TR_UNINITIALIZED = 0, 251 TR_IN_ORDER = 1, 252 TR_RANGE = 2, 253 }; 254 255 /* 256 #tr Pattern syntax 257 258 <syntax> ::= (<pattern>)* | '^' (<pattern>)* 259 <pattern> ::= <in order> | <range> 260 <in order> ::= (<ch>)+ 261 <range> ::= <ch> '-' <ch> 262 */ 263 struct tr_pattern { 264 uint8_t type; // 1:in-order, 2:range 265 mrb_bool flag_reverse : 1; 266 mrb_bool flag_on_heap : 1; 267 uint16_t n; 268 union { 269 uint16_t start_pos; 270 char ch[2]; 271 } val; 272 struct tr_pattern *next; 273 }; 274 275 #define STATIC_TR_PATTERN { 0 } 276 277 static inline void 278 tr_free_pattern(mrb_state *mrb, struct tr_pattern *pat) 279 { 280 while (pat) { 281 struct tr_pattern *p = pat->next; 282 if (pat->flag_on_heap) { 283 mrb_free(mrb, pat); 284 } 285 pat = p; 286 } 287 } 288 289 static struct tr_pattern* 290 tr_parse_pattern(mrb_state *mrb, struct tr_pattern *ret, const mrb_value v_pattern, mrb_bool flag_reverse_enable) 291 { 292 const char *pattern = RSTRING_PTR(v_pattern); 293 mrb_int pattern_length = RSTRING_LEN(v_pattern); 294 mrb_bool flag_reverse = FALSE; 295 struct tr_pattern *pat1; 296 mrb_int i = 0; 297 298 if(flag_reverse_enable && pattern_length >= 2 && pattern[0] == '^') { 299 flag_reverse = TRUE; 300 i++; 301 } 302 303 while (i < pattern_length) { 304 /* is range pattern ? */ 305 mrb_bool const ret_uninit = (ret->type == TR_UNINITIALIZED); 306 pat1 = ret_uninit 307 ? ret 308 : (struct tr_pattern*)mrb_malloc_simple(mrb, sizeof(struct tr_pattern)); 309 if ((i+2) < pattern_length && pattern[i] != '\\' && pattern[i+1] == '-') { 310 if (pat1 == NULL && ret) { 311 nomem: 312 tr_free_pattern(mrb, ret); 313 mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err)); 314 return NULL; /* not reached */ 315 } 316 pat1->type = TR_RANGE; 317 pat1->flag_reverse = flag_reverse; 318 pat1->flag_on_heap = !ret_uninit; 319 pat1->n = pattern[i+2] - pattern[i] + 1; 320 pat1->next = NULL; 321 pat1->val.ch[0] = pattern[i]; 322 pat1->val.ch[1] = pattern[i+2]; 323 i += 3; 324 } 325 else { 326 /* in order pattern. */ 327 mrb_int start_pos = i++; 328 mrb_int len; 329 330 while (i < pattern_length) { 331 if ((i+2) < pattern_length && pattern[i] != '\\' && pattern[i+1] == '-') 332 break; 333 i++; 334 } 335 336 len = i - start_pos; 337 if (len > UINT16_MAX) { 338 mrb_raise(mrb, E_ARGUMENT_ERROR, "tr pattern too long (max 65536)"); 339 } 340 if (pat1 == NULL && ret) { 341 goto nomem; 342 } 343 pat1->type = TR_IN_ORDER; 344 pat1->flag_reverse = flag_reverse; 345 pat1->flag_on_heap = !ret_uninit; 346 pat1->n = len; 347 pat1->next = NULL; 348 pat1->val.start_pos = start_pos; 349 } 350 351 if (ret == NULL || ret_uninit) { 352 ret = pat1; 353 } 354 else { 355 struct tr_pattern *p = ret; 356 while (p->next != NULL) { 357 p = p->next; 358 } 359 p->next = pat1; 360 } 361 } 362 363 return ret; 364 } 365 366 static inline mrb_int 367 tr_find_character(const struct tr_pattern *pat, const char *pat_str, int ch) 368 { 369 mrb_int ret = -1; 370 mrb_int n_sum = 0; 371 mrb_int flag_reverse = pat ? pat->flag_reverse : 0; 372 373 while (pat != NULL) { 374 if (pat->type == TR_IN_ORDER) { 375 int i; 376 for (i = 0; i < pat->n; i++) { 377 if (pat_str[pat->val.start_pos + i] == ch) ret = n_sum + i; 378 } 379 } 380 else if (pat->type == TR_RANGE) { 381 if (pat->val.ch[0] <= ch && ch <= pat->val.ch[1]) 382 ret = n_sum + ch - pat->val.ch[0]; 383 } 384 else { 385 mrb_assert(pat->type == TR_UNINITIALIZED); 386 } 387 n_sum += pat->n; 388 pat = pat->next; 389 } 390 391 if (flag_reverse) { 392 return (ret < 0) ? MRB_INT_MAX : -1; 393 } 394 return ret; 395 } 396 397 static inline mrb_int 398 tr_get_character(const struct tr_pattern *pat, const char *pat_str, mrb_int n_th) 399 { 400 mrb_int n_sum = 0; 401 402 while (pat != NULL) { 403 if (n_th < (n_sum + pat->n)) { 404 mrb_int i = (n_th - n_sum); 405 406 switch (pat->type) { 407 case TR_IN_ORDER: 408 return pat_str[pat->val.start_pos + i]; 409 case TR_RANGE: 410 return pat->val.ch[0]+i; 411 case TR_UNINITIALIZED: 412 return -1; 413 } 414 } 415 if (pat->next == NULL) { 416 switch (pat->type) { 417 case TR_IN_ORDER: 418 return pat_str[pat->val.start_pos + pat->n - 1]; 419 case TR_RANGE: 420 return pat->val.ch[1]; 421 case TR_UNINITIALIZED: 422 return -1; 423 } 424 } 425 n_sum += pat->n; 426 pat = pat->next; 427 } 428 429 return -1; 430 } 431 432 static inline void 433 tr_bitmap_set(uint8_t bitmap[32], uint8_t ch) 434 { 435 uint8_t idx1 = ch / 8; 436 uint8_t idx2 = ch % 8; 437 bitmap[idx1] |= (1<<idx2); 438 } 439 440 static inline mrb_bool 441 tr_bitmap_detect(uint8_t bitmap[32], uint8_t ch) 442 { 443 uint8_t idx1 = ch / 8; 444 uint8_t idx2 = ch % 8; 445 if (bitmap[idx1] & (1<<idx2)) 446 return TRUE; 447 return FALSE; 448 } 449 450 /* compile patter to bitmap */ 451 static void 452 tr_compile_pattern(const struct tr_pattern *pat, mrb_value pstr, uint8_t bitmap[32]) 453 { 454 const char *pattern = RSTRING_PTR(pstr); 455 mrb_int flag_reverse = pat ? pat->flag_reverse : 0; 456 int i; 457 458 for (i=0; i<32; i++) { 459 bitmap[i] = 0; 460 } 461 while (pat != NULL) { 462 if (pat->type == TR_IN_ORDER) { 463 for (i = 0; i < pat->n; i++) { 464 tr_bitmap_set(bitmap, pattern[pat->val.start_pos + i]); 465 } 466 } 467 else if (pat->type == TR_RANGE) { 468 for (i = pat->val.ch[0]; i < pat->val.ch[1]; i++) { 469 tr_bitmap_set(bitmap, i); 470 } 471 } 472 else { 473 mrb_assert(pat->type == TR_UNINITIALIZED); 474 } 475 pat = pat->next; 476 } 477 478 if (flag_reverse) { 479 for (i=0; i<32; i++) { 480 bitmap[i] ^= 0xff; 481 } 482 } 483 } 484 485 static mrb_bool 486 str_tr(mrb_state *mrb, mrb_value str, mrb_value p1, mrb_value p2, mrb_bool squeeze) 487 { 488 struct tr_pattern pat = STATIC_TR_PATTERN; 489 struct tr_pattern rep_storage = STATIC_TR_PATTERN; 490 char *s; 491 mrb_int len; 492 mrb_int i; 493 mrb_int j; 494 mrb_bool flag_changed = FALSE; 495 mrb_int lastch = -1; 496 struct tr_pattern *rep; 497 498 mrb_str_modify(mrb, mrb_str_ptr(str)); 499 tr_parse_pattern(mrb, &pat, p1, TRUE); 500 rep = tr_parse_pattern(mrb, &rep_storage, p2, FALSE); 501 s = RSTRING_PTR(str); 502 len = RSTRING_LEN(str); 503 504 for (i=j=0; i<len; i++,j++) { 505 mrb_int n = tr_find_character(&pat, RSTRING_PTR(p1), s[i]); 506 507 if (i>j) s[j] = s[i]; 508 if (n >= 0) { 509 flag_changed = TRUE; 510 if (rep == NULL) { 511 j--; 512 } 513 else { 514 mrb_int c = tr_get_character(rep, RSTRING_PTR(p2), n); 515 516 if (c < 0 || (squeeze && c == lastch)) { 517 j--; 518 continue; 519 } 520 if (c > 0x80) { 521 mrb_raisef(mrb, E_ARGUMENT_ERROR, "character (%i) out of range", c); 522 } 523 lastch = c; 524 s[i] = (char)c; 525 } 526 } 527 } 528 529 tr_free_pattern(mrb, &pat); 530 tr_free_pattern(mrb, rep); 531 532 if (flag_changed) { 533 RSTR_SET_LEN(RSTRING(str), j); 534 RSTRING_PTR(str)[j] = 0; 535 } 536 return flag_changed; 537 } 538 539 /* 540 * call-seq: 541 * str.tr(from_str, to_str) => new_str 542 * 543 * Returns a copy of str with the characters in from_str replaced by the 544 * corresponding characters in to_str. If to_str is shorter than from_str, 545 * it is padded with its last character in order to maintain the 546 * correspondence. 547 * 548 * "hello".tr('el', 'ip') #=> "hippo" 549 * "hello".tr('aeiou', '*') #=> "h*ll*" 550 * "hello".tr('aeiou', 'AA*') #=> "hAll*" 551 * 552 * Both strings may use the c1-c2 notation to denote ranges of characters, 553 * and from_str may start with a ^, which denotes all characters except 554 * those listed. 555 * 556 * "hello".tr('a-y', 'b-z') #=> "ifmmp" 557 * "hello".tr('^aeiou', '*') #=> "*e**o" 558 * 559 * The backslash character \ can be used to escape ^ or - and is otherwise 560 * ignored unless it appears at the end of a range or the end of the 561 * from_str or to_str: 562 * 563 * 564 * "hello^world".tr("\\^aeiou", "*") #=> "h*ll**w*rld" 565 * "hello-world".tr("a\\-eo", "*") #=> "h*ll**w*rld" 566 * 567 * "hello\r\nworld".tr("\r", "") #=> "hello\nworld" 568 * "hello\r\nworld".tr("\\r", "") #=> "hello\r\nwold" 569 * "hello\r\nworld".tr("\\\r", "") #=> "hello\nworld" 570 * 571 * "X['\\b']".tr("X\\", "") #=> "['b']" 572 * "X['\\b']".tr("X-\\]", "") #=> "'b'" 573 * 574 * Note: conversion is effective only in ASCII region. 575 */ 576 static mrb_value 577 mrb_str_tr(mrb_state *mrb, mrb_value str) 578 { 579 mrb_value dup; 580 mrb_value p1, p2; 581 582 mrb_get_args(mrb, "SS", &p1, &p2); 583 dup = mrb_str_dup(mrb, str); 584 str_tr(mrb, dup, p1, p2, FALSE); 585 return dup; 586 } 587 588 /* 589 * call-seq: 590 * str.tr!(from_str, to_str) -> str or nil 591 * 592 * Translates str in place, using the same rules as String#tr. 593 * Returns str, or nil if no changes were made. 594 */ 595 static mrb_value 596 mrb_str_tr_bang(mrb_state *mrb, mrb_value str) 597 { 598 mrb_value p1, p2; 599 600 mrb_get_args(mrb, "SS", &p1, &p2); 601 if (str_tr(mrb, str, p1, p2, FALSE)) { 602 return str; 603 } 604 return mrb_nil_value(); 605 } 606 607 /* 608 * call-seq: 609 * str.tr_s(from_str, to_str) -> new_str 610 * 611 * Processes a copy of str as described under String#tr, then removes 612 * duplicate characters in regions that were affected by the translation. 613 * 614 * "hello".tr_s('l', 'r') #=> "hero" 615 * "hello".tr_s('el', '*') #=> "h*o" 616 * "hello".tr_s('el', 'hx') #=> "hhxo" 617 */ 618 static mrb_value 619 mrb_str_tr_s(mrb_state *mrb, mrb_value str) 620 { 621 mrb_value dup; 622 mrb_value p1, p2; 623 624 mrb_get_args(mrb, "SS", &p1, &p2); 625 dup = mrb_str_dup(mrb, str); 626 str_tr(mrb, dup, p1, p2, TRUE); 627 return dup; 628 } 629 630 /* 631 * call-seq: 632 * str.tr_s!(from_str, to_str) -> str or nil 633 * 634 * Performs String#tr_s processing on str in place, returning 635 * str, or nil if no changes were made. 636 */ 637 static mrb_value 638 mrb_str_tr_s_bang(mrb_state *mrb, mrb_value str) 639 { 640 mrb_value p1, p2; 641 642 mrb_get_args(mrb, "SS", &p1, &p2); 643 if (str_tr(mrb, str, p1, p2, TRUE)) { 644 return str; 645 } 646 return mrb_nil_value(); 647 } 648 649 static mrb_bool 650 str_squeeze(mrb_state *mrb, mrb_value str, mrb_value v_pat) 651 { 652 struct tr_pattern pat_storage = STATIC_TR_PATTERN; 653 struct tr_pattern *pat = NULL; 654 mrb_int i, j; 655 char *s; 656 mrb_int len; 657 mrb_bool flag_changed = FALSE; 658 mrb_int lastch = -1; 659 uint8_t bitmap[32]; 660 661 mrb_str_modify(mrb, mrb_str_ptr(str)); 662 if (!mrb_nil_p(v_pat)) { 663 pat = tr_parse_pattern(mrb, &pat_storage, v_pat, TRUE); 664 tr_compile_pattern(pat, v_pat, bitmap); 665 tr_free_pattern(mrb, pat); 666 } 667 s = RSTRING_PTR(str); 668 len = RSTRING_LEN(str); 669 670 if (pat) { 671 for (i=j=0; i<len; i++,j++) { 672 if (i>j) s[j] = s[i]; 673 if (tr_bitmap_detect(bitmap, s[i]) && s[i] == lastch) { 674 flag_changed = TRUE; 675 j--; 676 } 677 lastch = s[i]; 678 } 679 } 680 else { 681 for (i=j=0; i<len; i++,j++) { 682 if (i>j) s[j] = s[i]; 683 if (s[i] >= 0 && s[i] == lastch) { 684 flag_changed = TRUE; 685 j--; 686 } 687 lastch = s[i]; 688 } 689 } 690 691 if (flag_changed) { 692 RSTR_SET_LEN(RSTRING(str), j); 693 RSTRING_PTR(str)[j] = 0; 694 } 695 return flag_changed; 696 } 697 698 /* 699 * call-seq: 700 * str.squeeze([other_str]) -> new_str 701 * 702 * Builds a set of characters from the other_str 703 * parameter(s) using the procedure described for String#count. Returns a 704 * new string where runs of the same character that occur in this set are 705 * replaced by a single character. If no arguments are given, all runs of 706 * identical characters are replaced by a single character. 707 * 708 * "yellow moon".squeeze #=> "yelow mon" 709 * " now is the".squeeze(" ") #=> " now is the" 710 * "putters shoot balls".squeeze("m-z") #=> "puters shot balls" 711 */ 712 static mrb_value 713 mrb_str_squeeze(mrb_state *mrb, mrb_value str) 714 { 715 mrb_value pat = mrb_nil_value(); 716 mrb_value dup; 717 718 mrb_get_args(mrb, "|S", &pat); 719 dup = mrb_str_dup(mrb, str); 720 str_squeeze(mrb, dup, pat); 721 return dup; 722 } 723 724 /* 725 * call-seq: 726 * str.squeeze!([other_str]) -> str or nil 727 * 728 * Squeezes str in place, returning either str, or nil if no 729 * changes were made. 730 */ 731 static mrb_value 732 mrb_str_squeeze_bang(mrb_state *mrb, mrb_value str) 733 { 734 mrb_value pat = mrb_nil_value(); 735 736 mrb_get_args(mrb, "|S", &pat); 737 if (str_squeeze(mrb, str, pat)) { 738 return str; 739 } 740 return mrb_nil_value(); 741 } 742 743 static mrb_bool 744 str_delete(mrb_state *mrb, mrb_value str, mrb_value v_pat) 745 { 746 struct tr_pattern pat = STATIC_TR_PATTERN; 747 mrb_int i, j; 748 char *s; 749 mrb_int len; 750 mrb_bool flag_changed = FALSE; 751 uint8_t bitmap[32]; 752 753 mrb_str_modify(mrb, mrb_str_ptr(str)); 754 tr_parse_pattern(mrb, &pat, v_pat, TRUE); 755 tr_compile_pattern(&pat, v_pat, bitmap); 756 tr_free_pattern(mrb, &pat); 757 758 s = RSTRING_PTR(str); 759 len = RSTRING_LEN(str); 760 761 for (i=j=0; i<len; i++,j++) { 762 if (i>j) s[j] = s[i]; 763 if (tr_bitmap_detect(bitmap, s[i])) { 764 flag_changed = TRUE; 765 j--; 766 } 767 } 768 if (flag_changed) { 769 RSTR_SET_LEN(RSTRING(str), j); 770 RSTRING_PTR(str)[j] = 0; 771 } 772 return flag_changed; 773 } 774 775 static mrb_value 776 mrb_str_delete(mrb_state *mrb, mrb_value str) 777 { 778 mrb_value pat; 779 mrb_value dup; 780 781 mrb_get_args(mrb, "S", &pat); 782 dup = mrb_str_dup(mrb, str); 783 str_delete(mrb, dup, pat); 784 return dup; 785 } 786 787 static mrb_value 788 mrb_str_delete_bang(mrb_state *mrb, mrb_value str) 789 { 790 mrb_value pat; 791 792 mrb_get_args(mrb, "S", &pat); 793 if (str_delete(mrb, str, pat)) { 794 return str; 795 } 796 return mrb_nil_value(); 797 } 798 799 /* 800 * call_seq: 801 * str.count([other_str]) -> integer 802 * 803 * Each other_str parameter defines a set of characters to count. The 804 * intersection of these sets defines the characters to count in str. Any 805 * other_str that starts with a caret ^ is negated. The sequence c1-c2 806 * means all characters between c1 and c2. The backslash character \ can 807 * be used to escape ^ or - and is otherwise ignored unless it appears at 808 * the end of a sequence or the end of a other_str. 809 */ 810 static mrb_value 811 mrb_str_count(mrb_state *mrb, mrb_value str) 812 { 813 mrb_value v_pat = mrb_nil_value(); 814 mrb_int i; 815 char *s; 816 mrb_int len; 817 mrb_int count = 0; 818 struct tr_pattern pat = STATIC_TR_PATTERN; 819 uint8_t bitmap[32]; 820 821 mrb_get_args(mrb, "S", &v_pat); 822 tr_parse_pattern(mrb, &pat, v_pat, TRUE); 823 tr_compile_pattern(&pat, v_pat, bitmap); 824 tr_free_pattern(mrb, &pat); 825 826 s = RSTRING_PTR(str); 827 len = RSTRING_LEN(str); 828 for (i = 0; i < len; i++) { 829 if (tr_bitmap_detect(bitmap, s[i])) count++; 830 } 831 return mrb_fixnum_value(count); 832 } 833 235 834 static mrb_value 236 835 mrb_str_hex(mrb_state *mrb, mrb_value self) … … 260 859 } 261 860 262 static mrb_value 263 mrb_fixnum_chr(mrb_state *mrb, mrb_value num) 264 { 265 mrb_int cp = mrb_fixnum(num); 861 /* 862 * call-seq: 863 * int.chr([encoding]) -> string 864 * 865 * Returns a string containing the character represented by the +int+'s value 866 * according to +encoding+. +"ASCII-8BIT"+ (+"BINARY"+) and +"UTF-8"+ (only 867 * with +MRB_UTF8_STRING+) can be specified as +encoding+ (default is 868 * +"ASCII-8BIT"+). 869 * 870 * 65.chr #=> "A" 871 * 230.chr #=> "\xE6" 872 * 230.chr("ASCII-8BIT") #=> "\xE6" 873 * 230.chr("UTF-8") #=> "\u00E6" 874 */ 875 static mrb_value 876 mrb_int_chr(mrb_state *mrb, mrb_value num) 877 { 878 mrb_value enc; 879 mrb_bool enc_given; 880 881 mrb_get_args(mrb, "|S?", &enc, &enc_given); 882 if (!enc_given || 883 ENC_COMP_P(enc, ENC_ASCII_8BIT) || 884 ENC_COMP_P(enc, ENC_BINARY)) { 885 return int_chr_binary(mrb, num); 886 } 266 887 #ifdef MRB_UTF8_STRING 267 char utf8[4]; 268 mrb_int len; 269 270 if (cp < 0 || 0x10FFFF < cp) { 271 mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", num); 272 } 273 if (cp < 0x80) { 274 utf8[0] = (char)cp; 275 len = 1; 276 } 277 else if (cp < 0x800) { 278 utf8[0] = (char)(0xC0 | (cp >> 6)); 279 utf8[1] = (char)(0x80 | (cp & 0x3F)); 280 len = 2; 281 } 282 else if (cp < 0x10000) { 283 utf8[0] = (char)(0xE0 | (cp >> 12)); 284 utf8[1] = (char)(0x80 | ((cp >> 6) & 0x3F)); 285 utf8[2] = (char)(0x80 | ( cp & 0x3F)); 286 len = 3; 287 } 888 else if (ENC_COMP_P(enc, ENC_UTF8)) { 889 return int_chr_utf8(mrb, num); 890 } 891 #endif 288 892 else { 289 utf8[0] = (char)(0xF0 | (cp >> 18)); 290 utf8[1] = (char)(0x80 | ((cp >> 12) & 0x3F)); 291 utf8[2] = (char)(0x80 | ((cp >> 6) & 0x3F)); 292 utf8[3] = (char)(0x80 | ( cp & 0x3F)); 293 len = 4; 294 } 295 return mrb_str_new(mrb, utf8, len); 296 #else 297 char c; 298 299 if (cp < 0 || 0xff < cp) { 300 mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", num); 301 } 302 c = (char)cp; 303 return mrb_str_new(mrb, &c, 1); 304 #endif 305 } 306 307 /* 308 * call-seq: 309 * string.lines -> array of string 310 * 311 * Returns strings per line; 312 * 313 * a = "abc\ndef" 314 * a.lines #=> ["abc\n", "def"] 315 */ 316 static mrb_value 317 mrb_str_lines(mrb_state *mrb, mrb_value self) 318 { 319 mrb_value result; 320 mrb_value blk; 321 int ai; 322 mrb_int len; 323 mrb_value arg; 324 char *b = RSTRING_PTR(self); 325 char *p = b, *t; 326 char *e = b + RSTRING_LEN(self); 327 328 mrb_get_args(mrb, "&", &blk); 329 330 result = mrb_ary_new(mrb); 331 ai = mrb_gc_arena_save(mrb); 332 if (!mrb_nil_p(blk)) { 333 while (p < e) { 334 t = p; 335 while (p < e && *p != '\n') p++; 336 if (*p == '\n') p++; 337 len = (mrb_int) (p - t); 338 arg = mrb_str_new(mrb, t, len); 339 mrb_yield_argv(mrb, blk, 1, &arg); 340 mrb_gc_arena_restore(mrb, ai); 341 if (b != RSTRING_PTR(self)) { 342 ptrdiff_t diff = p - b; 343 b = RSTRING_PTR(self); 344 p = b + diff; 345 } 346 e = b + RSTRING_LEN(self); 347 } 348 return self; 349 } 350 while (p < e) { 351 t = p; 352 while (p < e && *p != '\n') p++; 353 if (*p == '\n') p++; 354 len = (mrb_int) (p - t); 355 mrb_ary_push(mrb, result, mrb_str_new(mrb, t, len)); 356 mrb_gc_arena_restore(mrb, ai); 357 } 358 return result; 893 mrb_raisef(mrb, E_ARGUMENT_ERROR, "unknown encoding name - %v", enc); 894 } 895 /* not reached */ 896 return mrb_nil_value(); 359 897 } 360 898 … … 522 1060 #endif 523 1061 524 static mrb_bool525 all_digits_p(const char *s, mrb_int len)526 {527 while (len-- > 0) {528 if (!ISDIGIT(*s)) return FALSE;529 s++;530 }531 return TRUE;532 }533 534 1062 /* 535 1063 * call-seq: 536 * str.upto(other_str, exclusive=false) {|s| block } -> str 537 * str.upto(other_str, exclusive=false) -> an_enumerator 538 * 539 * Iterates through successive values, starting at <i>str</i> and 540 * ending at <i>other_str</i> inclusive, passing each value in turn to 541 * the block. The <code>String#succ</code> method is used to generate 542 * each value. If optional second argument exclusive is omitted or is false, 543 * the last value will be included; otherwise it will be excluded. 544 * 545 * If no block is given, an enumerator is returned instead. 546 * 547 * "a8".upto("b6") {|s| print s, ' ' } 548 * for s in "a8".."b6" 549 * print s, ' ' 550 * end 551 * 552 * <em>produces:</em> 553 * 554 * a8 a9 b0 b1 b2 b3 b4 b5 b6 555 * a8 a9 b0 b1 b2 b3 b4 b5 b6 556 * 557 * If <i>str</i> and <i>other_str</i> contains only ascii numeric characters, 558 * both are recognized as decimal numbers. In addition, the width of 559 * string (e.g. leading zeros) is handled appropriately. 560 * 561 * "9".upto("11").to_a #=> ["9", "10", "11"] 562 * "25".upto("5").to_a #=> [] 563 * "07".upto("11").to_a #=> ["07", "08", "09", "10", "11"] 564 */ 565 static mrb_value 566 mrb_str_upto(mrb_state *mrb, mrb_value beg) 567 { 568 mrb_value end; 569 mrb_value exclusive = mrb_false_value(); 570 mrb_value block = mrb_nil_value(); 571 mrb_value current, after_end; 572 mrb_int n; 573 mrb_bool excl; 574 575 mrb_get_args(mrb, "o|o&", &end, &exclusive, &block); 576 577 if (mrb_nil_p(block)) { 578 return mrb_funcall(mrb, beg, "to_enum", 3, mrb_symbol_value(mrb_intern_lit(mrb, "upto")), end, exclusive); 579 } 580 end = mrb_string_type(mrb, end); 581 excl = mrb_test(exclusive); 582 583 /* single character */ 584 if (RSTRING_LEN(beg) == 1 && RSTRING_LEN(end) == 1 && 585 ISASCII(RSTRING_PTR(beg)[0]) && ISASCII(RSTRING_PTR(end)[0])) { 586 char c = RSTRING_PTR(beg)[0]; 587 char e = RSTRING_PTR(end)[0]; 588 int ai = mrb_gc_arena_save(mrb); 589 590 if (c > e || (excl && c == e)) return beg; 591 for (;;) { 592 mrb_yield(mrb, block, mrb_str_new(mrb, &c, 1)); 593 mrb_gc_arena_restore(mrb, ai); 594 if (!excl && c == e) break; 595 c++; 596 if (excl && c == e) break; 597 } 598 return beg; 599 } 600 /* both edges are all digits */ 601 if (ISDIGIT(RSTRING_PTR(beg)[0]) && ISDIGIT(RSTRING_PTR(end)[0]) && 602 all_digits_p(RSTRING_PTR(beg), RSTRING_LEN(beg)) && 603 all_digits_p(RSTRING_PTR(end), RSTRING_LEN(end))) { 604 int ai = mrb_gc_arena_save(mrb); 605 mrb_int min_width = RSTRING_LEN(beg); 606 mrb_int max_width = RSTRING_LEN(end); 607 mrb_int bi = mrb_int(mrb, mrb_str_to_inum(mrb, beg, 10, FALSE)); 608 mrb_int ei = mrb_int(mrb, mrb_str_to_inum(mrb, end, 10, FALSE)); 609 mrb_value str = mrb_str_new(mrb, NULL, max_width); 610 char *buf = RSTRING_PTR(str); 611 612 while (bi <= ei) { 613 if (excl && bi == ei) break; 614 snprintf(buf, max_width+1, "%.*" MRB_PRId, (int)min_width, bi); 615 mrb_yield(mrb, block, mrb_str_new(mrb, buf, strlen(buf))); 616 mrb_gc_arena_restore(mrb, ai); 617 bi++; 618 } 619 620 return beg; 621 } 622 /* normal case */ 623 n = mrb_int(mrb, mrb_funcall(mrb, beg, "<=>", 1, end)); 624 if (n > 0 || (excl && n == 0)) return beg; 625 626 after_end = mrb_funcall(mrb, end, "succ", 0); 627 current = mrb_str_dup(mrb, beg); 628 while (!mrb_str_equal(mrb, current, after_end)) { 629 int ai = mrb_gc_arena_save(mrb); 630 mrb_value next = mrb_nil_value(); 631 if (excl || !mrb_str_equal(mrb, current, end)) 632 next = mrb_funcall(mrb, current, "succ", 0); 633 mrb_yield(mrb, block, current); 634 if (mrb_nil_p(next)) break; 635 current = mrb_str_to_str(mrb, next); 636 if (excl && mrb_str_equal(mrb, current, end)) break; 637 if (RSTRING_LEN(current) > RSTRING_LEN(end) || RSTRING_LEN(current) == 0) 638 break; 1064 * str.delete_prefix!(prefix) -> self or nil 1065 * 1066 * Deletes leading <code>prefix</code> from <i>str</i>, returning 1067 * <code>nil</code> if no change was made. 1068 * 1069 * "hello".delete_prefix!("hel") #=> "lo" 1070 * "hello".delete_prefix!("llo") #=> nil 1071 */ 1072 static mrb_value 1073 mrb_str_del_prefix_bang(mrb_state *mrb, mrb_value self) 1074 { 1075 mrb_int plen, slen; 1076 char *ptr, *s; 1077 struct RString *str = RSTRING(self); 1078 1079 mrb_get_args(mrb, "s", &ptr, &plen); 1080 slen = RSTR_LEN(str); 1081 if (plen > slen) return mrb_nil_value(); 1082 s = RSTR_PTR(str); 1083 if (memcmp(s, ptr, plen) != 0) return mrb_nil_value(); 1084 if (!mrb_frozen_p(str) && (RSTR_SHARED_P(str) || RSTR_FSHARED_P(str))) { 1085 str->as.heap.ptr += plen; 1086 } 1087 else { 1088 mrb_str_modify(mrb, str); 1089 s = RSTR_PTR(str); 1090 memmove(s, s+plen, slen-plen); 1091 } 1092 RSTR_SET_LEN(str, slen-plen); 1093 return self; 1094 } 1095 1096 /* 1097 * call-seq: 1098 * str.delete_prefix(prefix) -> new_str 1099 * 1100 * Returns a copy of <i>str</i> with leading <code>prefix</code> deleted. 1101 * 1102 * "hello".delete_prefix("hel") #=> "lo" 1103 * "hello".delete_prefix("llo") #=> "hello" 1104 */ 1105 static mrb_value 1106 mrb_str_del_prefix(mrb_state *mrb, mrb_value self) 1107 { 1108 mrb_int plen, slen; 1109 char *ptr; 1110 1111 mrb_get_args(mrb, "s", &ptr, &plen); 1112 slen = RSTRING_LEN(self); 1113 if (plen > slen) return mrb_str_dup(mrb, self); 1114 if (memcmp(RSTRING_PTR(self), ptr, plen) != 0) 1115 return mrb_str_dup(mrb, self); 1116 return mrb_str_substr(mrb, self, plen, slen-plen); 1117 } 1118 1119 /* 1120 * call-seq: 1121 * str.delete_suffix!(suffix) -> self or nil 1122 * 1123 * Deletes trailing <code>suffix</code> from <i>str</i>, returning 1124 * <code>nil</code> if no change was made. 1125 * 1126 * "hello".delete_suffix!("llo") #=> "he" 1127 * "hello".delete_suffix!("hel") #=> nil 1128 */ 1129 static mrb_value 1130 mrb_str_del_suffix_bang(mrb_state *mrb, mrb_value self) 1131 { 1132 mrb_int plen, slen; 1133 char *ptr, *s; 1134 struct RString *str = RSTRING(self); 1135 1136 mrb_get_args(mrb, "s", &ptr, &plen); 1137 slen = RSTR_LEN(str); 1138 if (plen > slen) return mrb_nil_value(); 1139 s = RSTR_PTR(str); 1140 if (memcmp(s+slen-plen, ptr, plen) != 0) return mrb_nil_value(); 1141 if (!mrb_frozen_p(str) && (RSTR_SHARED_P(str) || RSTR_FSHARED_P(str))) { 1142 /* no need to modify string */ 1143 } 1144 else { 1145 mrb_str_modify(mrb, str); 1146 } 1147 RSTR_SET_LEN(str, slen-plen); 1148 return self; 1149 } 1150 1151 /* 1152 * call-seq: 1153 * str.delete_suffix(suffix) -> new_str 1154 * 1155 * Returns a copy of <i>str</i> with leading <code>suffix</code> deleted. 1156 * 1157 * "hello".delete_suffix("hel") #=> "lo" 1158 * "hello".delete_suffix("llo") #=> "hello" 1159 */ 1160 static mrb_value 1161 mrb_str_del_suffix(mrb_state *mrb, mrb_value self) 1162 { 1163 mrb_int plen, slen; 1164 char *ptr; 1165 1166 mrb_get_args(mrb, "s", &ptr, &plen); 1167 slen = RSTRING_LEN(self); 1168 if (plen > slen) return mrb_str_dup(mrb, self); 1169 if (memcmp(RSTRING_PTR(self)+slen-plen, ptr, plen) != 0) 1170 return mrb_str_dup(mrb, self); 1171 return mrb_str_substr(mrb, self, 0, slen-plen); 1172 } 1173 1174 static mrb_value 1175 mrb_str_lines(mrb_state *mrb, mrb_value self) 1176 { 1177 mrb_value result; 1178 int ai; 1179 mrb_int len; 1180 char *b = RSTRING_PTR(self); 1181 char *p = b, *t; 1182 char *e = b + RSTRING_LEN(self); 1183 1184 result = mrb_ary_new(mrb); 1185 ai = mrb_gc_arena_save(mrb); 1186 while (p < e) { 1187 t = p; 1188 while (p < e && *p != '\n') p++; 1189 if (*p == '\n') p++; 1190 len = (mrb_int) (p - t); 1191 mrb_ary_push(mrb, result, mrb_str_new(mrb, t, len)); 639 1192 mrb_gc_arena_restore(mrb, ai); 640 1193 } 641 642 return beg; 1194 return result; 643 1195 } 644 1196 … … 649 1201 650 1202 mrb_define_method(mrb, s, "dump", mrb_str_dump, MRB_ARGS_NONE()); 651 mrb_define_method(mrb, s, "getbyte", mrb_str_getbyte, MRB_ARGS_REQ(1));652 mrb_define_method(mrb, s, "setbyte", mrb_str_setbyte, MRB_ARGS_REQ(2));653 mrb_define_method(mrb, s, "byteslice", mrb_str_byteslice, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1));654 1203 mrb_define_method(mrb, s, "swapcase!", mrb_str_swapcase_bang, MRB_ARGS_NONE()); 655 1204 mrb_define_method(mrb, s, "swapcase", mrb_str_swapcase, MRB_ARGS_NONE()); 656 mrb_define_method(mrb, s, "concat", mrb_str_concat2, MRB_ARGS_REQ(1)); 657 mrb_define_method(mrb, s, "<<", mrb_str_concat2, MRB_ARGS_REQ(1)); 1205 mrb_define_method(mrb, s, "concat", mrb_str_concat_m, MRB_ARGS_REQ(1)); 1206 mrb_define_method(mrb, s, "<<", mrb_str_concat_m, MRB_ARGS_REQ(1)); 1207 mrb_define_method(mrb, s, "count", mrb_str_count, MRB_ARGS_REQ(1)); 1208 mrb_define_method(mrb, s, "tr", mrb_str_tr, MRB_ARGS_REQ(2)); 1209 mrb_define_method(mrb, s, "tr!", mrb_str_tr_bang, MRB_ARGS_REQ(2)); 1210 mrb_define_method(mrb, s, "tr_s", mrb_str_tr_s, MRB_ARGS_REQ(2)); 1211 mrb_define_method(mrb, s, "tr_s!", mrb_str_tr_s_bang, MRB_ARGS_REQ(2)); 1212 mrb_define_method(mrb, s, "squeeze", mrb_str_squeeze, MRB_ARGS_OPT(1)); 1213 mrb_define_method(mrb, s, "squeeze!", mrb_str_squeeze_bang, MRB_ARGS_OPT(1)); 1214 mrb_define_method(mrb, s, "delete", mrb_str_delete, MRB_ARGS_REQ(1)); 1215 mrb_define_method(mrb, s, "delete!", mrb_str_delete_bang, MRB_ARGS_REQ(1)); 658 1216 mrb_define_method(mrb, s, "start_with?", mrb_str_start_with, MRB_ARGS_REST()); 659 1217 mrb_define_method(mrb, s, "end_with?", mrb_str_end_with, MRB_ARGS_REST()); … … 661 1219 mrb_define_method(mrb, s, "oct", mrb_str_oct, MRB_ARGS_NONE()); 662 1220 mrb_define_method(mrb, s, "chr", mrb_str_chr, MRB_ARGS_NONE()); 663 mrb_define_method(mrb, s, "lines", mrb_str_lines, MRB_ARGS_NONE());664 1221 mrb_define_method(mrb, s, "succ", mrb_str_succ, MRB_ARGS_NONE()); 665 1222 mrb_define_method(mrb, s, "succ!", mrb_str_succ_bang, MRB_ARGS_NONE()); 666 mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "next"), mrb_intern_lit(mrb, "succ")); 667 mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "next!"), mrb_intern_lit(mrb, "succ!")); 668 mrb_define_method(mrb, s, "ord", mrb_str_ord, MRB_ARGS_NONE()); 669 mrb_define_method(mrb, s, "upto", mrb_str_upto, MRB_ARGS_ANY()); 670 671 mrb_define_method(mrb, mrb->fixnum_class, "chr", mrb_fixnum_chr, MRB_ARGS_NONE()); 1223 mrb_define_method(mrb, s, "next", mrb_str_succ, MRB_ARGS_NONE()); 1224 mrb_define_method(mrb, s, "next!", mrb_str_succ_bang, MRB_ARGS_NONE()); 1225 mrb_define_method(mrb, s, "ord", mrb_str_ord, MRB_ARGS_NONE()); 1226 mrb_define_method(mrb, s, "delete_prefix!", mrb_str_del_prefix_bang, MRB_ARGS_REQ(1)); 1227 mrb_define_method(mrb, s, "delete_prefix", mrb_str_del_prefix, MRB_ARGS_REQ(1)); 1228 mrb_define_method(mrb, s, "delete_suffix!", mrb_str_del_suffix_bang, MRB_ARGS_REQ(1)); 1229 mrb_define_method(mrb, s, "delete_suffix", mrb_str_del_suffix, MRB_ARGS_REQ(1)); 1230 1231 mrb_define_method(mrb, s, "__lines", mrb_str_lines, MRB_ARGS_NONE()); 1232 1233 mrb_define_method(mrb, mrb_module_get(mrb, "Integral"), "chr", mrb_int_chr, MRB_ARGS_OPT(1)); 672 1234 } 673 1235 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-string-ext/test/string.rb
r331 r439 1 # coding: utf-8 1 2 ## 2 3 # String(Ext) Test 3 4 4 UTF8STRING = ("\343\201\202".size == 1) 5 6 assert('String.try_convert') do 7 assert_nil String.try_convert(nil) 8 assert_nil String.try_convert(:foo) 9 assert_equal "", String.try_convert("") 10 assert_equal "1,2,3", String.try_convert("1,2,3") 11 end 12 13 assert('String#getbyte') do 14 str1 = "hello" 15 bytes1 = [104, 101, 108, 108, 111] 16 assert_equal bytes1[0], str1.getbyte(0) 17 assert_equal bytes1[-1], str1.getbyte(-1) 18 assert_equal bytes1[6], str1.getbyte(6) 19 20 str2 = "\xFF" 21 bytes2 = [0xFF] 22 assert_equal bytes2[0], str2.getbyte(0) 23 end 24 25 assert('String#setbyte') do 26 str1 = "hello" 27 h = "H".getbyte(0) 28 str1.setbyte(0, h) 29 assert_equal(h, str1.getbyte(0)) 30 assert_equal("Hello", str1) 31 end 32 33 assert("String#setbyte raises IndexError if arg conversion resizes String") do 34 $s = "01234\n" 35 class Tmp 36 def to_i 37 $s.chomp! '' 38 95 39 end 40 end 41 tmp = Tmp.new 42 assert_raise(IndexError) { $s.setbyte(5, tmp) } 43 end 44 45 assert('String#byteslice') do 46 str1 = "hello" 47 assert_equal("e", str1.byteslice(1)) 48 assert_equal("o", str1.byteslice(-1)) 49 assert_equal("ell", str1.byteslice(1..3)) 50 assert_equal("el", str1.byteslice(1...3)) 5 UTF8STRING = __ENCODING__ == "UTF-8" 6 7 def assert_upto(exp, receiver, *args) 8 act = [] 9 receiver.upto(*args) { |v| act << v } 10 assert_equal exp, act 51 11 end 52 12 53 13 assert('String#dump') do 54 ("\1" * 100).dump # should not raise an exception - regress #1210 55 "\0".inspect == "\"\\000\"" and 56 "foo".dump == "\"foo\"" 14 assert_equal("\"\\x00\"", "\0".dump) 15 assert_equal("\"foo\"", "foo".dump) 16 assert_equal('"\xe3\x82\x8b"', "る".dump) 17 assert_nothing_raised { ("\1" * 100).dump } # regress #1210 57 18 end 58 19 59 20 assert('String#strip') do 60 21 s = " abc " 61 "".strip == "" and " \t\r\n\f\v".strip == "" and 62 "\0a\0".strip == "\0a" and 63 "abc".strip == "abc" and 64 " abc".strip == "abc" and 65 "abc ".strip == "abc" and 66 " abc ".strip == "abc" and 67 s == " abc " 22 assert_equal("abc", s.strip) 23 assert_equal(" abc ", s) 24 assert_equal("", "".strip) 25 assert_equal("", " \t\r\n\f\v".strip) 26 assert_equal("\0a", "\0a\0".strip) 27 assert_equal("abc", "abc".strip) 28 assert_equal("abc", " abc".strip) 29 assert_equal("abc", "abc ".strip) 68 30 end 69 31 70 32 assert('String#lstrip') do 71 33 s = " abc " 72 s.lstrip73 "".lstrip == "" and " \t\r\n\f\v".lstrip == "" and74 "\0a\0".lstrip == "\0a\0" and75 "abc".lstrip == "abc" and76 " abc".lstrip == "abc" and77 "abc ".lstrip == "abc " and78 " abc ".lstrip == "abc " and79 s == " abc "34 assert_equal("abc ", s.lstrip) 35 assert_equal(" abc ", s) 36 assert_equal("", "".lstrip) 37 assert_equal("", " \t\r\n\f\v".lstrip) 38 assert_equal("\0a\0", "\0a\0".lstrip) 39 assert_equal("abc", "abc".lstrip) 40 assert_equal("abc", " abc".lstrip) 41 assert_equal("abc ", "abc ".lstrip) 80 42 end 81 43 82 44 assert('String#rstrip') do 83 45 s = " abc " 84 s.rstrip85 "".rstrip == "" and " \t\r\n\f\v".rstrip == "" and86 "\0a\0".rstrip == "\0a" and87 "abc".rstrip == "abc" and88 " abc".rstrip == " abc" and89 "abc ".rstrip == "abc" and90 " abc ".rstrip == " abc" and91 s == " abc "46 assert_equal(" abc", s.rstrip) 47 assert_equal(" abc ", s) 48 assert_equal("", "".rstrip) 49 assert_equal("", " \t\r\n\f\v".rstrip) 50 assert_equal("\0a", "\0a\0".rstrip) 51 assert_equal("abc", "abc".rstrip) 52 assert_equal(" abc", " abc".rstrip) 53 assert_equal("abc", "abc ".rstrip) 92 54 end 93 55 … … 95 57 s = " abc " 96 58 t = "abc" 97 s.strip! == "abc" and s == "abc" and t.strip! == nil 59 assert_equal("abc", s.strip!) 60 assert_equal("abc", s) 61 assert_nil(t.strip!) 62 assert_equal("abc", t) 98 63 end 99 64 … … 101 66 s = " abc " 102 67 t = "abc " 103 s.lstrip! == "abc " and s == "abc " and t.lstrip! == nil 68 assert_equal("abc ", s.lstrip!) 69 assert_equal("abc ", s) 70 assert_nil(t.lstrip!) 71 assert_equal("abc ", t) 104 72 end 105 73 … … 107 75 s = " abc " 108 76 t = " abc" 109 s.rstrip! == " abc" and s == " abc" and t.rstrip! == nil 77 assert_equal(" abc", s.rstrip!) 78 assert_equal(" abc", s) 79 assert_nil(t.rstrip!) 80 assert_equal(" abc", t) 110 81 end 111 82 … … 125 96 assert_equal "Hello World!", "Hello " << "World" << 33 126 97 assert_equal "Hello World!", "Hello ".concat("World").concat(33) 127 128 o = Object.new129 def o.to_str130 "to_str"131 end132 assert_equal "hi to_str", "hi " << o133 134 98 assert_raise(TypeError) { "".concat(Object.new) } 99 100 if UTF8STRING 101 assert_equal "H«", "H" << 0xab 102 assert_equal "Hは", "H" << 12399 103 else 104 assert_equal "H\xab", "H" << 0xab 105 assert_raise(RangeError) { "H" << 12399 } 106 end 135 107 end 136 108 … … 140 112 assert_equal(-1, "abcdef".casecmp("abcdefg")) 141 113 assert_equal 0, "abcdef".casecmp("ABCDEF") 142 o = Object.new 143 def o.to_str 144 "ABCDEF" 145 end 146 assert_equal 0, "abcdef".casecmp(o) 114 end 115 116 assert('String#count') do 117 s = "abccdeff123" 118 assert_equal 0, s.count("") 119 assert_equal 1, s.count("a") 120 assert_equal 2, s.count("ab") 121 assert_equal 9, s.count("^c") 122 assert_equal 8, s.count("a-z") 123 assert_equal 4, s.count("a0-9") 124 end 125 126 assert('String#tr') do 127 assert_equal "ABC", "abc".tr('a-z', 'A-Z') 128 assert_equal "hippo", "hello".tr('el', 'ip') 129 assert_equal "Ruby", "Lisp".tr("Lisp", "Ruby") 130 assert_equal "*e**o", "hello".tr('^aeiou', '*') 131 assert_equal "heo", "hello".tr('l', '') 132 end 133 134 assert('String#tr!') do 135 s = "abcdefghijklmnopqR" 136 assert_equal "ab12222hijklmnopqR", s.tr!("cdefg", "12") 137 assert_equal "ab12222hijklmnopqR", s 138 end 139 140 assert('String#tr_s') do 141 assert_equal "hero", "hello".tr_s('l', 'r') 142 assert_equal "h*o", "hello".tr_s('el', '*') 143 assert_equal "hhxo", "hello".tr_s('el', 'hx') 144 end 145 146 assert('String#tr_s!') do 147 s = "hello" 148 assert_equal "hero", s.tr_s!('l', 'r') 149 assert_equal "hero", s 150 assert_nil s.tr_s!('l', 'r') 151 end 152 153 assert('String#squeeze') do 154 assert_equal "yelow mon", "yellow moon".squeeze 155 assert_equal " now is the", " now is the".squeeze(" ") 156 assert_equal "puters shot balls", "putters shoot balls".squeeze("m-z") 157 end 158 159 assert('String#squeeze!') do 160 s = " now is the" 161 assert_equal " now is the", s.squeeze!(" ") 162 assert_equal " now is the", s 163 end 164 165 assert('String#delete') do 166 assert_equal "he", "hello".delete("lo") 167 assert_equal "hll", "hello".delete("aeiou") 168 assert_equal "ll", "hello".delete("^l") 169 assert_equal "ho", "hello".delete("ej-m") 170 end 171 172 assert('String#delete!') do 173 s = "hello" 174 assert_equal "he", s.delete!("lo") 175 assert_equal "he", s 176 assert_nil s.delete!("lz") 147 177 end 148 178 … … 202 232 assert_equal 8, "010".oct 203 233 assert_equal (-8), "-10".oct 204 end205 206 assert('String#chr') do207 assert_equal "a", "abcde".chr208 # test Fixnum#chr as well209 assert_equal "a", 97.chr210 234 end 211 235 … … 496 520 497 521 assert('String#upto') do 498 assert_equal %w(a8 a9 b0 b1 b2 b3 b4 b5 b6), "a8".upto("b6").to_a 499 assert_equal ["9", "10", "11"], "9".upto("11").to_a 500 assert_equal [], "25".upto("5").to_a 501 assert_equal ["07", "08", "09", "10", "11"], "07".upto("11").to_a 502 503 if UTF8STRING 504 assert_equal ["あ", "ぃ", "い", "ぅ", "う", "ぇ", "え", "ぉ", "お"], "あ".upto("お").to_a 505 end 506 507 assert_equal ["9", ":", ";", "<", "=", ">", "?", "@", "A"], "9".upto("A").to_a 522 assert_upto %w(a8 a9 b0 b1 b2 b3 b4 b5 b6), "a8", "b6" 523 assert_upto ["9", "10", "11"], "9", "11" 524 assert_upto [], "25", "5" 525 assert_upto ["07", "08", "09", "10", "11"], "07", "11" 526 assert_upto ["9", ":", ";", "<", "=", ">", "?", "@", "A"], "9", "A" 527 528 if UTF8STRING 529 assert_upto %w(あ ぃ い ぅ う ぇ え ぉ お), "あ", "お" 530 end 508 531 509 532 a = "aa" … … 587 610 588 611 assert('String#chr') do 612 assert_equal "a", "abcde".chr 589 613 assert_equal "h", "hello!".chr 590 end 614 assert_equal "", "".chr 615 end 616 591 617 assert('String#chr(UTF-8)') do 592 618 assert_equal "こ", "こんにちは世界!".chr … … 614 640 615 641 assert('String#each_char') do 616 s = ""642 chars = [] 617 643 "hello!".each_char do |x| 618 s +=x619 end 620 assert_equal "hello!",s644 chars << x 645 end 646 assert_equal ["h", "e", "l", "l", "o", "!"], chars 621 647 end 622 648 623 649 assert('String#each_char(UTF-8)') do 624 s = ""650 chars = [] 625 651 "こんにちは世界!".each_char do |x| 626 s +=x627 end 628 assert_equal "こんにちは世界!",s652 chars << x 653 end 654 assert_equal ["こ", "ん", "に", "ち", "は", "世", "界", "!"], chars 629 655 end if UTF8STRING 630 656 … … 666 692 assert_equal expect, cp 667 693 end if UTF8STRING 694 695 assert('String#delete_prefix') do 696 assert_equal "llo", "hello".delete_prefix("he") 697 assert_equal "hello", "hello".delete_prefix("llo") 698 assert_equal "llo", "hello".delete_prefix!("he") 699 assert_nil "hello".delete_prefix!("llo") 700 end 701 702 assert('String#delete_suffix') do 703 assert_equal "he", "hello".delete_suffix("llo") 704 assert_equal "hello", "hello".delete_suffix("he") 705 assert_equal "he", "hello".delete_suffix!("llo") 706 assert_nil "hello".delete_suffix!("he") 707 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-struct/mrblib/struct.rb
r331 r439 47 47 end 48 48 49 def _inspect 49 def _inspect(recur_list) 50 return "#<struct #{self.class}:...>" if recur_list[self.object_id] 51 recur_list[self.object_id] = true 50 52 name = self.class.to_s 51 53 if name[0] == "#" … … 56 58 buf = [] 57 59 self.each_pair do |k,v| 58 buf.push [k.to_s + "=" + v._inspect]60 buf.push k.to_s + "=" + v._inspect(recur_list) 59 61 end 60 62 str + buf.join(", ") + ">" … … 71 73 # 72 74 def inspect 73 begin 74 self._inspect 75 rescue SystemStackError 76 "#<struct #{self.class.to_s}:...>" 77 end 75 self._inspect({}) 78 76 end 79 77 … … 82 80 # 83 81 alias to_s inspect 84 end85 82 86 ## 87 # call-seq: 88 # hsh.dig(key,...) -> object 89 # 90 # Extracts the nested value specified by the sequence of <i>key</i> 91 # objects by calling +dig+ at each step, returning +nil+ if any 92 # intermediate step is +nil+. 93 # 94 def dig(idx,*args) 95 n = self[idx] 96 if args.size > 0 97 n&.dig(*args) 98 else 99 n 83 ## 84 # call-seq: 85 # hsh.dig(key,...) -> object 86 # 87 # Extracts the nested value specified by the sequence of <i>key</i> 88 # objects by calling +dig+ at each step, returning +nil+ if any 89 # intermediate step is +nil+. 90 # 91 def dig(idx,*args) 92 n = self[idx] 93 if args.size > 0 94 n&.dig(*args) 95 else 96 n 97 end 100 98 end 101 99 end 102 100 end 103 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-struct/src/struct.c
r331 r439 13 13 #include <mruby/hash.h> 14 14 #include <mruby/range.h> 15 16 #define RSTRUCT_LEN(st) mrb_ary_ptr(st)->len 17 #define RSTRUCT_PTR(st) mrb_ary_ptr(st)->ptr 15 #include <mruby/proc.h> 16 17 #define RSTRUCT_LEN(st) RARRAY_LEN(st) 18 #define RSTRUCT_PTR(st) RARRAY_PTR(st) 18 19 19 20 static struct RClass * … … 24 25 25 26 static inline mrb_value 26 struct_ivar_get(mrb_state *mrb, mrb_value c , mrb_sym id)27 { 28 struct RClass* kclass;27 struct_ivar_get(mrb_state *mrb, mrb_value cls, mrb_sym id) 28 { 29 struct RClass* c = mrb_class_ptr(cls); 29 30 struct RClass* sclass = struct_class(mrb); 30 31 mrb_value ans; 31 32 32 33 for (;;) { 33 ans = mrb_iv_get(mrb, c, id);34 ans = mrb_iv_get(mrb, mrb_obj_value(c), id); 34 35 if (!mrb_nil_p(ans)) return ans; 35 kclass = RCLASS_SUPER(c);36 if ( kclass == 0 || kclass == sclass)36 c = c->super; 37 if (c == sclass || c == 0) 37 38 return mrb_nil_value(); 38 c = mrb_obj_value(kclass);39 39 } 40 40 } … … 67 67 else { 68 68 mrb_raisef(mrb, E_TYPE_ERROR, 69 "struct size differs (% S required %Sgiven)",70 mrb_fixnum_value(RARRAY_LEN(members)), mrb_fixnum_value(RSTRUCT_LEN(s)));69 "struct size differs (%i required %i given)", 70 RARRAY_LEN(members), RSTRUCT_LEN(s)); 71 71 } 72 72 } … … 88 88 mrb_struct_modify(mrb_state *mrb, mrb_value strct) 89 89 { 90 if (MRB_FROZEN_P(mrb_basic_ptr(strct))) { 91 mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen struct"); 92 } 93 90 mrb_check_frozen(mrb, mrb_basic_ptr(strct)); 94 91 mrb_write_barrier(mrb, mrb_basic_ptr(strct)); 95 92 } … … 114 111 } 115 112 116 static mrb_value struct_aref_sym(mrb_state *mrb, mrb_value obj, mrb_sym id);117 118 113 static mrb_value 119 114 mrb_struct_ref(mrb_state *mrb, mrb_value obj) 120 115 { 121 return struct_aref_sym(mrb, obj, mrb->c->ci->mid); 116 mrb_int i = mrb_fixnum(mrb_proc_cfunc_env_get(mrb, 0)); 117 mrb_value *ptr = RSTRUCT_PTR(obj); 118 119 if (!ptr) return mrb_nil_value(); 120 return ptr[i]; 122 121 } 123 122 … … 125 124 mrb_id_attrset(mrb_state *mrb, mrb_sym id) 126 125 { 126 #define ONSTACK_ALLOC_MAX 32 127 #define ONSTACK_STRLEN_MAX (ONSTACK_ALLOC_MAX - 1) /* '=' character */ 128 127 129 const char *name; 128 130 char *buf; 129 131 mrb_int len; 130 132 mrb_sym mid; 131 132 name = mrb_sym2name_len(mrb, id, &len); 133 buf = (char *)mrb_malloc(mrb, (size_t)len+2); 133 char onstack[ONSTACK_ALLOC_MAX]; 134 135 name = mrb_sym_name_len(mrb, id, &len); 136 if (len > ONSTACK_STRLEN_MAX) { 137 buf = (char *)mrb_malloc(mrb, (size_t)len+1); 138 } 139 else { 140 buf = onstack; 141 } 134 142 memcpy(buf, name, (size_t)len); 135 143 buf[len] = '='; 136 buf[len+1] = '\0';137 144 138 145 mid = mrb_intern(mrb, buf, len+1); 139 mrb_free(mrb, buf); 146 if (buf != onstack) { 147 mrb_free(mrb, buf); 148 } 140 149 return mid; 141 150 } 142 151 143 static mrb_value mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val);144 145 152 static mrb_value 146 153 mrb_struct_set_m(mrb_state *mrb, mrb_value obj) 147 154 { 155 mrb_int i = mrb_fixnum(mrb_proc_cfunc_env_get(mrb, 0)); 156 mrb_value *ptr; 148 157 mrb_value val; 149 158 150 const char *name;151 mrb_int slen;152 mrb_sym mid;153 154 159 mrb_get_args(mrb, "o", &val); 155 156 /* get base id */ 157 name = mrb_sym2name_len(mrb, mrb->c->ci->mid, &slen); 158 mid = mrb_intern(mrb, name, slen-1); /* omit last "=" */ 159 160 return mrb_struct_aset_sym(mrb, obj, mid, val); 161 } 162 163 static mrb_bool 164 is_local_id(mrb_state *mrb, const char *name) 165 { 166 if (!name) return FALSE; 167 return !ISUPPER(name[0]); 168 } 169 170 static mrb_bool 171 is_const_id(mrb_state *mrb, const char *name) 172 { 173 if (!name) return FALSE; 174 return ISUPPER(name[0]); 160 mrb_struct_modify(mrb, obj); 161 ptr = RSTRUCT_PTR(obj); 162 if (ptr == NULL || i >= RSTRUCT_LEN(obj)) { 163 mrb_ary_set(mrb, obj, i, val); 164 } 165 else { 166 ptr[i] = val; 167 } 168 return val; 175 169 } 176 170 … … 185 179 for (i=0; i<len; i++) { 186 180 mrb_sym id = mrb_symbol(ptr_members[i]); 187 const char *name = mrb_sym2name_len(mrb, id, NULL); 188 189 if (is_local_id(mrb, name) || is_const_id(mrb, name)) { 190 mrb_define_method_id(mrb, c, id, mrb_struct_ref, MRB_ARGS_NONE()); 191 mrb_define_method_id(mrb, c, mrb_id_attrset(mrb, id), mrb_struct_set_m, MRB_ARGS_REQ(1)); 192 mrb_gc_arena_restore(mrb, ai); 193 } 194 } 195 } 196 197 static mrb_value 198 make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * klass) 181 mrb_method_t m; 182 mrb_value at = mrb_fixnum_value(i); 183 struct RProc *aref = mrb_proc_new_cfunc_with_env(mrb, mrb_struct_ref, 1, &at); 184 struct RProc *aset = mrb_proc_new_cfunc_with_env(mrb, mrb_struct_set_m, 1, &at); 185 MRB_METHOD_FROM_PROC(m, aref); 186 mrb_define_method_raw(mrb, c, id, m); 187 MRB_METHOD_FROM_PROC(m, aset); 188 mrb_define_method_raw(mrb, c, mrb_id_attrset(mrb, id), m); 189 mrb_gc_arena_restore(mrb, ai); 190 } 191 } 192 193 static mrb_value 194 make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass *klass) 199 195 { 200 196 mrb_value nstr; … … 207 203 else { 208 204 /* old style: should we warn? */ 209 name = mrb_str_to_str(mrb, name);205 mrb_to_str(mrb, name); 210 206 id = mrb_obj_to_sym(mrb, name); 211 if (! is_const_id(mrb, mrb_sym2name_len(mrb, id, NULL))) {212 mrb_name_error(mrb, id, "identifier % Sneeds to be constant", name);207 if (!mrb_const_name_p(mrb, RSTRING_PTR(name), RSTRING_LEN(name))) { 208 mrb_name_error(mrb, id, "identifier %v needs to be constant", name); 213 209 } 214 210 if (mrb_const_defined_at(mrb, mrb_obj_value(klass), id)) { 215 mrb_warn(mrb, "redefining constant Struct::% S", name);211 mrb_warn(mrb, "redefining constant Struct::%v", name); 216 212 mrb_const_remove(mrb, mrb_obj_value(klass), id); 217 213 } … … 277 273 278 274 name = mrb_nil_value(); 279 rest = mrb_nil_value();280 275 mrb_get_args(mrb, "*&", &argv, &argc, &b); 281 276 if (argc == 0) { /* special case to avoid crash */ 282 rest = mrb_ary_new(mrb);277 mrb_argnum_error(mrb, argc, 1, -1); 283 278 } 284 279 else { 285 if (argc > 0) name = argv[0]; 286 pargv = &argv[1]; 287 argcnt = argc-1; 288 if (!mrb_nil_p(name) && mrb_symbol_p(name)) { 289 /* 1stArgument:symbol -> name=nil rest=argv[0]-[n] */ 290 name = mrb_nil_value(); 291 pargv = &argv[0]; 292 argcnt++; 280 pargv = argv; 281 argcnt = argc; 282 if (argc > 0) { 283 name = argv[0]; 284 if (mrb_symbol_p(name)) { 285 /* 1stArgument:symbol -> name=nil rest=argv[0..n] */ 286 name = mrb_nil_value(); 287 } 288 else { 289 pargv++; 290 argcnt--; 291 } 293 292 } 294 293 rest = mrb_ary_new_from_values(mrb, argcnt, pargv); 295 for (i=0; i< RARRAY_LEN(rest); i++) {294 for (i=0; i<argcnt; i++) { 296 295 id = mrb_obj_to_sym(mrb, RARRAY_PTR(rest)[i]); 297 296 mrb_ary_set(mrb, rest, i, mrb_symbol_value(id)); 298 297 } 299 } 300 st = make_struct(mrb, name, rest, mrb_class_ptr(klass)); 301 if (!mrb_nil_p(b)) { 302 mrb_yield_with_class(mrb, b, 1, &st, st, mrb_class_ptr(st)); 303 } 304 305 return st; 298 st = make_struct(mrb, name, rest, mrb_class_ptr(klass)); 299 if (!mrb_nil_p(b)) { 300 mrb_yield_with_class(mrb, b, 1, &st, st, mrb_class_ptr(st)); 301 } 302 303 return st; 304 } 305 /* not reached */ 306 return mrb_nil_value(); 306 307 } 307 308 … … 347 348 mrb_int argc; 348 349 349 mrb_get_args(mrb, "* ", &argv, &argc);350 mrb_get_args(mrb, "*!", &argv, &argc); 350 351 return mrb_struct_initialize_withArg(mrb, argc, argv, self); 351 352 } … … 388 389 } 389 390 } 390 mrb_ raisef(mrb, E_INDEX_ERROR, "'%S' is not a struct member", mrb_sym2str(mrb, id));391 mrb_name_error(mrb, id, "no member '%n' in struct", id); 391 392 return mrb_nil_value(); /* not reached */ 392 393 } … … 395 396 struct_aref_int(mrb_state *mrb, mrb_value s, mrb_int i) 396 397 { 397 if (i < 0) i = RSTRUCT_LEN(s) + i; 398 if (i < 0) 399 mrb_raisef(mrb, E_INDEX_ERROR, 400 "offset %S too small for struct(size:%S)", 401 mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s))); 402 if (RSTRUCT_LEN(s) <= i) 398 mrb_int idx = i < 0 ? RSTRUCT_LEN(s) + i : i; 399 400 if (idx < 0) 403 401 mrb_raisef(mrb, E_INDEX_ERROR, 404 "offset %S too large for struct(size:%S)", 405 mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s))); 406 return RSTRUCT_PTR(s)[i]; 402 "offset %i too small for struct(size:%i)", i, RSTRUCT_LEN(s)); 403 if (RSTRUCT_LEN(s) <= idx) 404 mrb_raisef(mrb, E_INDEX_ERROR, 405 "offset %i too large for struct(size:%i)", i, RSTRUCT_LEN(s)); 406 return RSTRUCT_PTR(s)[idx]; 407 407 } 408 408 … … 436 436 437 437 if (mrb_nil_p(sym)) { 438 mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '% S' in struct", idx);438 mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%v' in struct", idx); 439 439 } 440 440 idx = sym; … … 464 464 } 465 465 } 466 mrb_name_error(mrb, id, "no member '% S' in struct", mrb_sym2str(mrb, id));466 mrb_name_error(mrb, id, "no member '%n' in struct", id); 467 467 return val; /* not reach */ 468 468 } … … 503 503 504 504 if (mrb_nil_p(sym)) { 505 mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '% S' in struct", idx);505 mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%v' in struct", idx); 506 506 } 507 507 idx = sym; … … 515 515 if (i < 0) { 516 516 mrb_raisef(mrb, E_INDEX_ERROR, 517 "offset %S too small for struct(size:%S)", 518 mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s))); 517 "offset %i too small for struct(size:%i)", i, RSTRUCT_LEN(s)); 519 518 } 520 519 if (RSTRUCT_LEN(s) <= i) { 521 520 mrb_raisef(mrb, E_INDEX_ERROR, 522 "offset %S too large for struct(size:%S)", 523 mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s))); 521 "offset %i too large for struct(size:%i)", i, RSTRUCT_LEN(s)); 524 522 } 525 523 mrb_struct_modify(mrb, s); -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-struct/test/struct.rb
r331 r439 10 10 assert_equal Struct, c.superclass 11 11 assert_equal [:m1, :m2], c.members 12 end13 14 # Check crash bug with Struc.new and no params.15 assert('Struct.new', '15.2.18.3.1') do16 c = Struct.new()17 assert_equal Struct, c.superclass18 assert_equal [], c.members19 12 end 20 13 … … 124 117 125 118 assert('struct inspect') do 126 c = Struct.new(:m1, :m2, :m3, :m4, :m5) 127 cc = c.new(1,2,3,4,5) 128 assert_equal "#<struct m1=1, m2=2, m3=3, m4=4, m5=5>", cc.inspect 119 c = Struct.new(:m1, :m2, :m3, :m4, :m5, :recur) 120 cc = c.new(1,2,3,4,5,nil) 121 cc.recur = cc 122 assert_equal "#<struct m1=1, m2=2, m3=3, m4=4, m5=5, recur=#<struct #{cc.class}:...>>", cc.inspect 129 123 end 130 124 … … 160 154 end 161 155 162 assert("Struct.new removes existing constant") do 163 skip "redefining Struct with same name cause warnings" 164 begin165 assert_not_equal Struct.new("Test", :a), Struct.new("Test", :a, :b)166 ensure167 Struct.remove_const :Test168 end169 end156 # TODO: suppress redefining Struct warning during test 157 # assert("Struct.new removes existing constant") do 158 # begin 159 # assert_not_equal Struct.new("Test", :a), Struct.new("Test", :a, :b) 160 # ensure 161 # Struct.remove_const :Test 162 # end 163 # end 170 164 171 165 assert("Struct#initialize_copy requires struct to be the same type") do … … 189 183 end 190 184 185 assert("Struct.new does not allow invalid class name") do 186 assert_raise(NameError) { Struct.new("Test-", :a) } 187 end 188 191 189 assert("Struct.new generates subclass of Struct") do 192 190 begin 193 191 original_struct = Struct 194 192 Struct = String 195 assert_equal original_struct, original_struct.new .superclass193 assert_equal original_struct, original_struct.new(:foo).superclass 196 194 ensure 197 195 Struct = original_struct … … 207 205 208 206 o.freeze 209 assert_raise( RuntimeError) { o.m = :modify }210 assert_raise( RuntimeError) { o[:m] = :modify }207 assert_raise(FrozenError) { o.m = :modify } 208 assert_raise(FrozenError) { o[:m] = :modify } 211 209 assert_equal :test, o.m 212 210 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-symbol-ext/mrblib/symbol.rb
r321 r439 3 3 4 4 alias intern to_sym 5 6 def to_proc7 ->(obj,*args,&block) do8 obj.__send__(self, *args, &block)9 end10 end11 5 12 6 ## … … 49 43 return nil unless other.kind_of?(Symbol) 50 44 lhs = self.to_s; lhs.upcase! 51 rhs = other.to_s ; rhs.upcase!45 rhs = other.to_s.upcase 52 46 lhs <=> rhs 47 end 48 49 ## 50 # call-seq: 51 # sym.casecmp?(other) -> true, false, or nil 52 # 53 # Returns true if sym and other_sym are equal after case folding, 54 # false if they are not equal, and nil if other_sym is not a string. 55 56 def casecmp?(sym) 57 c = self.casecmp(sym) 58 return nil if c.nil? 59 return c == 0 53 60 end 54 61 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-symbol-ext/src/symbol.c
r331 r439 2 2 #include <mruby/khash.h> 3 3 #include <mruby/array.h> 4 5 typedef struct symbol_name { 6 size_t len; 7 const char *name; 8 } symbol_name; 4 #include <mruby/string.h> 9 5 10 6 /* … … 23 19 * :wait2, :$>] 24 20 */ 21 #ifdef MRB_ENABLE_ALL_SYMBOLS 25 22 static mrb_value 26 23 mrb_sym_all_symbols(mrb_state *mrb, mrb_value self) … … 30 27 31 28 for (i=1, lim=mrb->symidx+1; i<lim; i++) { 32 mrb_ary_push(mrb, ary, mrb_symbol_value(i)); 29 mrb_sym sym = i<<1; 30 mrb_ary_push(mrb, ary, mrb_symbol_value(sym)); 33 31 } 34 32 35 33 return ary; 36 34 } 35 #endif 37 36 38 37 /* … … 46 45 { 47 46 mrb_int len; 48 mrb_sym2name_len(mrb, mrb_symbol(self), &len); 47 #ifdef MRB_UTF8_STRING 48 mrb_int byte_len; 49 const char *name = mrb_sym_name_len(mrb, mrb_symbol(self), &byte_len); 50 len = mrb_utf8_strlen(name, byte_len); 51 #else 52 mrb_sym_name_len(mrb, mrb_symbol(self), &len); 53 #endif 49 54 return mrb_fixnum_value(len); 50 55 } … … 54 59 { 55 60 struct RClass *s = mrb->symbol_class; 61 #ifdef MRB_ENABLE_ALL_SYMBOLS 56 62 mrb_define_class_method(mrb, s, "all_symbols", mrb_sym_all_symbols, MRB_ARGS_NONE()); 63 #endif 57 64 mrb_define_method(mrb, s, "length", mrb_sym_length, MRB_ARGS_NONE()); 58 65 mrb_define_method(mrb, s, "size", mrb_sym_length, MRB_ARGS_NONE()); -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-symbol-ext/test/symbol.rb
r321 r439 1 # coding: utf-8 1 2 ## 2 3 # Symbol(Ext) Test 3 4 4 assert('Symbol#to_proc') do 5 assert_equal 5, :abs.to_proc[-5] 5 if Symbol.respond_to?(:all_symbols) 6 assert('Symbol.all_symbols') do 7 foo = [:__symbol_test_1, :__symbol_test_2, :__symbol_test_3].sort 8 symbols = Symbol.all_symbols.select{|sym|sym.to_s.include? '__symbol_test'}.sort 9 assert_equal foo, symbols 10 end 6 11 end 7 12 8 assert('Symbol.all_symbols') do 9 foo = [:__symbol_test_1, :__symbol_test_2, :__symbol_test_3].sort 10 symbols = Symbol.all_symbols.select{|sym|sym.to_s.include? '__symbol_test'}.sort 11 assert_equal foo, symbols 12 end 13 14 assert("Symbol#length") do 15 assert_equal 5, :hello.size 16 assert_equal 5, :mruby.length 13 %w[size length].each do |n| 14 assert("Symbol##{n}") do 15 assert_equal 5, :hello.__send__(n) 16 assert_equal 4, :"aA\0b".__send__(n) 17 if __ENCODING__ == "UTF-8" 18 assert_equal 8, :"こんにちは世界!".__send__(n) 19 assert_equal 4, :"aあ\0b".__send__(n) 20 else 21 assert_equal 22, :"こんにちは世界!".__send__(n) 22 assert_equal 6, :"aあ\0b".__send__(n) 23 end 24 end 17 25 end 18 26 -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-test/driver.c
r331 r439 19 19 #include <mruby/array.h> 20 20 21 void 22 mrb_init_mrbtest(mrb_state *); 21 extern const uint8_t mrbtest_assert_irep[]; 22 23 void mrbgemtest_init(mrb_state* mrb); 24 void mrb_init_test_vformat(mrb_state* mrb); 23 25 24 26 /* Print a short remark for the user */ … … 30 32 31 33 static int 32 check_error(mrb_state *mrb)33 {34 /* Error check */35 /* $ko_test and $kill_test should be 0 */36 mrb_value ko_test = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$ko_test"));37 mrb_value kill_test = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$kill_test"));38 39 return mrb_fixnum_p(ko_test) && mrb_fixnum(ko_test) == 0 && mrb_fixnum_p(kill_test) && mrb_fixnum(kill_test) == 0;40 }41 42 static int43 34 eval_test(mrb_state *mrb) 44 35 { 45 36 /* evaluate the test */ 46 mrb_ funcall(mrb, mrb_top_self(mrb), "report", 0);37 mrb_value result = mrb_funcall(mrb, mrb_top_self(mrb), "report", 0); 47 38 /* did an exception occur? */ 48 39 if (mrb->exc) { … … 51 42 return EXIT_FAILURE; 52 43 } 53 else if (!check_error(mrb)) { 54 return EXIT_FAILURE; 55 } 56 return EXIT_SUCCESS; 57 } 58 59 static void 60 t_printstr(mrb_state *mrb, mrb_value obj) 61 { 62 char *s; 63 int len; 64 65 if (mrb_string_p(obj)) { 66 s = RSTRING_PTR(obj); 67 len = RSTRING_LEN(obj); 68 fwrite(s, len, 1, stdout); 69 } 70 } 71 72 mrb_value 73 mrb_t_printstr(mrb_state *mrb, mrb_value self) 74 { 75 mrb_value argv; 76 77 mrb_get_args(mrb, "o", &argv); 78 t_printstr(mrb, argv); 79 80 return argv; 44 else { 45 return mrb_bool(result) ? EXIT_SUCCESS : EXIT_FAILURE; 46 } 47 } 48 49 /* Implementation of print due to the reason that there might be no print */ 50 static mrb_value 51 t_print(mrb_state *mrb, mrb_value self) 52 { 53 mrb_value *argv; 54 mrb_int argc; 55 mrb_int i; 56 57 mrb_get_args(mrb, "*!", &argv, &argc); 58 for (i = 0; i < argc; ++i) { 59 mrb_value s = mrb_obj_as_string(mrb, argv[i]); 60 fwrite(RSTRING_PTR(s), RSTRING_LEN(s), 1, stdout); 61 } 62 fflush(stdout); 63 64 return mrb_nil_value(); 65 } 66 67 #define UNESCAPE(p, endp) ((p) != (endp) && *(p) == '\\' ? (p)+1 : (p)) 68 #define CHAR_CMP(c1, c2) ((unsigned char)(c1) - (unsigned char)(c2)) 69 70 static const char * 71 str_match_bracket(const char *p, const char *pat_end, 72 const char *s, const char *str_end) 73 { 74 mrb_bool ok = FALSE, negated = FALSE; 75 76 if (p == pat_end) return NULL; 77 if (*p == '!' || *p == '^') { 78 negated = TRUE; 79 ++p; 80 } 81 82 while (*p != ']') { 83 const char *t1 = p; 84 if ((t1 = UNESCAPE(t1, pat_end)) == pat_end) return NULL; 85 if ((p = t1 + 1) == pat_end) return NULL; 86 if (p[0] == '-' && p[1] != ']') { 87 const char *t2 = p + 1; 88 if ((t2 = UNESCAPE(t2, pat_end)) == pat_end) return NULL; 89 p = t2 + 1; 90 if (!ok && CHAR_CMP(*t1, *s) <= 0 && CHAR_CMP(*s, *t2) <= 0) ok = TRUE; 91 } 92 else { 93 if (!ok && CHAR_CMP(*t1, *s) == 0) ok = TRUE; 94 } 95 } 96 97 return ok == negated ? NULL : p + 1; 98 } 99 100 static mrb_bool 101 str_match_no_brace_p(const char *pat, mrb_int pat_len, 102 const char *str, mrb_int str_len) 103 { 104 const char *p = pat, *s = str; 105 const char *pat_end = pat + pat_len, *str_end = str + str_len; 106 const char *p_tmp = NULL, *s_tmp = NULL; 107 108 for (;;) { 109 if (p == pat_end) return s == str_end; 110 switch (*p) { 111 case '*': 112 do { ++p; } while (p != pat_end && *p == '*'); 113 if (UNESCAPE(p, pat_end) == pat_end) return TRUE; 114 if (s == str_end) return FALSE; 115 p_tmp = p; 116 s_tmp = s; 117 continue; 118 case '?': 119 if (s == str_end) return FALSE; 120 ++p; 121 ++s; 122 continue; 123 case '[': { 124 const char *t; 125 if (s == str_end) return FALSE; 126 if ((t = str_match_bracket(p+1, pat_end, s, str_end))) { 127 p = t; 128 ++s; 129 continue; 130 } 131 goto L_failed; 132 } 133 } 134 135 /* ordinary */ 136 p = UNESCAPE(p, pat_end); 137 if (s == str_end) return p == pat_end; 138 if (p == pat_end) goto L_failed; 139 if (*p++ != *s++) goto L_failed; 140 continue; 141 142 L_failed: 143 if (p_tmp && s_tmp) { 144 /* try next '*' position */ 145 p = p_tmp; 146 s = ++s_tmp; 147 continue; 148 } 149 150 return FALSE; 151 } 152 } 153 154 #define COPY_AND_INC(dst, src, len) \ 155 do { memcpy(dst, src, len); dst += len; } while (0) 156 157 static mrb_bool 158 str_match_p(mrb_state *mrb, 159 const char *pat, mrb_int pat_len, 160 const char *str, mrb_int str_len) 161 { 162 const char *p = pat, *pat_end = pat + pat_len; 163 const char *lbrace = NULL, *rbrace = NULL; 164 int nest = 0; 165 mrb_bool ret = FALSE; 166 167 for (; p != pat_end; ++p) { 168 if (*p == '{' && nest++ == 0) lbrace = p; 169 else if (*p == '}' && lbrace && --nest == 0) { rbrace = p; break; } 170 else if (*p == '\\' && ++p == pat_end) break; 171 } 172 173 if (lbrace && rbrace) { 174 /* expand brace */ 175 char *ex_pat = (char *)mrb_malloc(mrb, pat_len-2); /* expanded pattern */ 176 char *ex_p = ex_pat; 177 178 COPY_AND_INC(ex_p, pat, lbrace-pat); 179 p = lbrace; 180 while (p < rbrace) { 181 char *orig_ex_p = ex_p; 182 const char *t = ++p; 183 for (nest = 0; p < rbrace && !(*p == ',' && nest == 0); ++p) { 184 if (*p == '{') ++nest; 185 else if (*p == '}') --nest; 186 else if (*p == '\\' && ++p == rbrace) break; 187 } 188 COPY_AND_INC(ex_p, t, p-t); 189 COPY_AND_INC(ex_p, rbrace+1, pat_end-rbrace-1); 190 if ((ret = str_match_p(mrb, ex_pat, ex_p-ex_pat, str, str_len))) break; 191 ex_p = orig_ex_p; 192 } 193 mrb_free(mrb, ex_pat); 194 } 195 else if (!lbrace && !rbrace) { 196 ret = str_match_no_brace_p(pat, pat_len, str, str_len); 197 } 198 199 return ret; 200 } 201 202 static mrb_value 203 m_str_match_p(mrb_state *mrb, mrb_value self) 204 { 205 const char *pat, *str; 206 mrb_int pat_len, str_len; 207 208 mrb_get_args(mrb, "ss", &pat, &pat_len, &str, &str_len); 209 return mrb_bool_value(str_match_p(mrb, pat, pat_len, str, str_len)); 81 210 } 82 211 … … 87 216 88 217 krn = mrb->kernel_module; 89 mrb_define_method(mrb, krn, "__t_printstr__", mrb_t_printstr, MRB_ARGS_REQ(1)); 218 mrb_define_method(mrb, krn, "t_print", t_print, MRB_ARGS_ANY()); 219 mrb_define_method(mrb, krn, "_str_match?", m_str_match_p, MRB_ARGS_REQ(2)); 90 220 91 221 mrbtest = mrb_define_module(mrb, "Mrbtest"); … … 95 225 mrb_define_const(mrb, mrbtest, "FIXNUM_BIT", mrb_fixnum_value(MRB_INT_BIT)); 96 226 227 #ifndef MRB_WITHOUT_FLOAT 97 228 #ifdef MRB_USE_FLOAT 98 229 mrb_define_const(mrb, mrbtest, "FLOAT_TOLERANCE", mrb_float_value(mrb, 1e-6)); … … 100 231 mrb_define_const(mrb, mrbtest, "FLOAT_TOLERANCE", mrb_float_value(mrb, 1e-12)); 101 232 #endif 233 #endif 234 235 mrb_init_test_vformat(mrb); 102 236 103 237 if (verbose) { … … 128 262 TEST_COUNT_PASS(ko_test); 129 263 TEST_COUNT_PASS(kill_test); 264 TEST_COUNT_PASS(warning_test); 265 TEST_COUNT_PASS(skip_test); 130 266 131 267 #undef TEST_COUNT_PASS … … 165 301 166 302 mrb_init_test_driver(mrb, verbose); 167 mrb_init_mrbtest(mrb); 303 mrb_load_irep(mrb, mrbtest_assert_irep); 304 mrbgemtest_init(mrb); 168 305 ret = eval_test(mrb); 169 306 mrb_close(mrb); -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-test/mrbgem.rake
r331 r439 13 13 exec = exefile("#{build.build_dir}/bin/mrbtest") 14 14 15 libmruby = libfile("#{build.build_dir}/lib/libmruby")16 libmruby_core = libfile("#{build.build_dir}/lib/libmruby_core")17 18 15 mrbtest_lib = libfile("#{build_dir}/mrbtest") 19 16 mrbtest_objs = [] 20 17 21 driver_obj = objfile("#{build_dir}/driver") 22 driver = "#{spec.dir}/driver.c" 18 driver_objs = Dir.glob("#{dir}/*.{c,cpp,cxx,cc,m,asm,s,S}").map do |f| 19 objfile(f.relative_path_from(dir).to_s.pathmap("#{build_dir}/%X")) 20 end 23 21 24 22 assert_c = "#{build_dir}/assert.c" … … 28 26 29 27 file assert_lib => assert_c 30 file assert_c => assert_rbdo |t|28 file assert_c => [assert_rb, build.mrbcfile] do |t| 31 29 open(t.name, 'w') do |f| 32 30 mrbc.run f, assert_rb, 'mrbtest_assert_irep' … … 42 40 43 41 file test_rbobj => g.test_rbireps 44 file g.test_rbireps => [g.test_rbfiles ].flatten do |t|45 FileUtils.mkdir_p File.dirname(t.name)42 file g.test_rbireps => [g.test_rbfiles, build.mrbcfile].flatten do |t| 43 mkdir_p File.dirname(t.name) 46 44 open(t.name, 'w') do |f| 47 45 g.print_gem_test_header(f) … … 98 96 f.puts %Q[ if (mrb2->exc) {] 99 97 f.puts %Q[ mrb_print_error(mrb2);] 98 f.puts %Q[ mrb_close(mrb2);] 100 99 f.puts %Q[ exit(EXIT_FAILURE);] 101 100 f.puts %Q[ }] … … 136 135 137 136 unless build.build_mrbtest_lib_only? 138 file exec => [ driver_obj, mlib, mrbtest_lib, libmruby_core, libmruby] do |t|137 file exec => [*driver_objs, mlib, mrbtest_lib, build.libmruby_static] do |t| 139 138 gem_flags = build.gems.map { |g| g.linker.flags } 140 139 gem_flags_before_libraries = build.gems.map { |g| g.linker.flags_before_libraries } … … 142 141 gem_libraries = build.gems.map { |g| g.linker.libraries } 143 142 gem_library_paths = build.gems.map { |g| g.linker.library_paths } 144 build.linker.run t.name, t.prerequisites, gem_libraries, gem_library_paths, gem_flags, gem_flags_before_libraries 143 build.linker.run t.name, t.prerequisites, gem_libraries, gem_library_paths, gem_flags, 144 gem_flags_before_libraries, gem_flags_after_libraries 145 145 end 146 146 end 147 148 init = "#{spec.dir}/init_mrbtest.c"149 147 150 148 # store the last gem selection and make the re-build 151 149 # of the test gem depending on a change to the gem 152 150 # selection 153 active_gems = "#{build_dir}/active_gems.lst"154 FileUtils.mkdir_p File.dirname(active_gems)155 open(active_gems, 'w+') do |f|156 build.gems.each do |g|157 f.puts g.name158 end151 active_gems_path = "#{build_dir}/active_gems_path.lst" 152 active_gem_list = File.read active_gems_path if File.exist? active_gems_path 153 current_gem_list = build.gems.map(&:name).join("\n") 154 task active_gems_path do |_t| 155 mkdir_p File.dirname(active_gems_path) 156 File.write active_gems_path, current_gem_list 159 157 end 160 file clib => active_gems 158 file clib => active_gems_path if active_gem_list != current_gem_list 161 159 162 160 file mlib => clib 163 file clib => init do |t|161 file clib => [build.mrbcfile, __FILE__] do |_t| 164 162 _pp "GEN", "*.rb", "#{clib.relative_path}" 165 FileUtils.mkdir_p File.dirname(clib)163 mkdir_p File.dirname(clib) 166 164 open(clib, 'w') do |f| 167 165 f.puts %Q[/*] … … 174 172 f.puts %Q[ */] 175 173 f.puts %Q[] 176 f.puts IO.read(init) 174 f.puts %Q[struct mrb_state;] 175 f.puts %Q[typedef struct mrb_state mrb_state;] 177 176 build.gems.each do |g| 178 177 f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb);] -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-time/src/time.c
r331 r439 5 5 */ 6 6 7 #ifndef MRB_WITHOUT_FLOAT 7 8 #include <math.h> 8 #include <time.h> 9 #endif 10 9 11 #include <mruby.h> 10 12 #include <mruby/class.h> 11 13 #include <mruby/data.h> 12 13 #i fndef DISABLE_STDIO14 #include <stdio.h> 15 # else14 #include <mruby/numeric.h> 15 #include <mruby/time.h> 16 17 #ifdef MRB_DISABLE_STDIO 16 18 #include <string.h> 17 19 #endif 18 20 21 #include <stdlib.h> 22 19 23 #define NDIV(x,y) (-(-((x)+1)/(y))-1) 20 21 #if _MSC_VER < 1800 24 #define TO_S_FMT "%Y-%m-%d %H:%M:%S " 25 26 #if defined(_MSC_VER) && _MSC_VER < 1800 22 27 double round(double x) { 23 if (x >= 0.0) { 24 return (double)((int)(x + 0.5)); 25 } 26 else { 27 return (double)((int)(x - 0.5)); 28 } 29 } 30 #endif 31 32 #if !defined(__MINGW64__) && defined(_WIN32) 33 # define llround(x) round(x) 28 return floor(x + 0.5); 29 } 30 #endif 31 32 #ifndef MRB_WITHOUT_FLOAT 33 # if !defined(__MINGW64__) && defined(_WIN32) 34 # define llround(x) round(x) 35 # endif 34 36 #endif 35 37 … … 52 54 53 55 #ifdef _WIN32 54 #if _MSC_VER56 #ifdef _MSC_VER 55 57 /* Win32 platform do not provide gmtime_r/localtime_r; emulate them using gmtime_s/localtime_s */ 56 58 #define gmtime_r(tp, tm) ((gmtime_s((tm), (tp)) == 0) ? (tm) : NULL) … … 144 146 unsigned int *nday = (unsigned int*) ndays[is_leapyear(tm->tm_year+1900)]; 145 147 146 for (i = 70; i < tm->tm_year; ++i) 147 r += is_leapyear(i+1900) ? 366*24*60*60 : 365*24*60*60; 148 static const int epoch_year = 70; 149 if(tm->tm_year >= epoch_year) { 150 for (i = epoch_year; i < tm->tm_year; ++i) 151 r += is_leapyear(i+1900) ? 366*24*60*60 : 365*24*60*60; 152 } else { 153 for (i = tm->tm_year; i < epoch_year; ++i) 154 r -= is_leapyear(i+1900) ? 366*24*60*60 : 365*24*60*60; 155 } 148 156 for (i = 0; i < tm->tm_mon; ++i) 149 157 r += nday[i] * 24 * 60 * 60; … … 161 169 */ 162 170 163 enum mrb_timezone {164 MRB_TIMEZONE_NONE = 0,165 MRB_TIMEZONE_UTC = 1,166 MRB_TIMEZONE_LOCAL = 2,167 MRB_TIMEZONE_LAST = 3168 };169 170 171 typedef struct mrb_timezone_name { 171 172 const char name[8]; … … 179 180 }; 180 181 181 #ifndef DISABLE_STDIO182 #ifndef MRB_DISABLE_STDIO 182 183 static const char mon_names[12][4] = { 183 184 "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", … … 198 199 static const struct mrb_data_type mrb_time_type = { "Time", mrb_free }; 199 200 201 #ifndef MRB_WITHOUT_FLOAT 202 void mrb_check_num_exact(mrb_state *mrb, mrb_float num); 203 typedef mrb_float mrb_sec; 204 #define mrb_sec_value(mrb, sec) mrb_float_value(mrb, sec) 205 #else 206 typedef mrb_int mrb_sec; 207 #define mrb_sec_value(mrb, sec) mrb_fixnum_value(sec) 208 #endif 209 210 #define MRB_TIME_T_UINT (~(time_t)0 > 0) 211 #define MRB_TIME_MIN ( \ 212 MRB_TIME_T_UINT ? 0 : \ 213 (sizeof(time_t) <= 4 ? INT32_MIN : INT64_MIN) \ 214 ) 215 #define MRB_TIME_MAX ( \ 216 MRB_TIME_T_UINT ? (sizeof(time_t) <= 4 ? UINT32_MAX : UINT64_MAX) : \ 217 (sizeof(time_t) <= 4 ? INT32_MAX : INT64_MAX) \ 218 ) 219 220 static mrb_bool 221 fixable_time_t_p(time_t v) 222 { 223 if (MRB_INT_MIN <= MRB_TIME_MIN && MRB_TIME_MAX <= MRB_INT_MAX) return TRUE; 224 return FIXABLE(v); 225 } 226 227 static time_t 228 mrb_to_time_t(mrb_state *mrb, mrb_value obj, time_t *usec) 229 { 230 time_t t; 231 232 switch (mrb_type(obj)) { 233 #ifndef MRB_WITHOUT_FLOAT 234 case MRB_TT_FLOAT: 235 { 236 mrb_float f = mrb_float(obj); 237 238 mrb_check_num_exact(mrb, f); 239 if (f >= ((mrb_float)MRB_TIME_MAX-1.0) || f < ((mrb_float)MRB_TIME_MIN+1.0)) { 240 goto out_of_range; 241 } 242 243 if (usec) { 244 t = (time_t)f; 245 *usec = (time_t)llround((f - t) * 1.0e+6); 246 } 247 else { 248 t = (time_t)llround(f); 249 } 250 } 251 break; 252 #endif /* MRB_WITHOUT_FLOAT */ 253 default: 254 case MRB_TT_FIXNUM: 255 { 256 mrb_int i = mrb_int(mrb, obj); 257 258 if ((MRB_INT_MAX > MRB_TIME_MAX && i > 0 && i > (mrb_int)MRB_TIME_MAX) || 259 (MRB_TIME_MIN > MRB_INT_MIN && MRB_TIME_MIN > i)) { 260 goto out_of_range; 261 } 262 263 t = (time_t)i; 264 if (usec) { *usec = 0; } 265 } 266 break; 267 } 268 269 return t; 270 271 out_of_range: 272 mrb_raisef(mrb, E_ARGUMENT_ERROR, "%v out of Time range", obj); 273 274 /* not reached */ 275 if (usec) { *usec = 0; } 276 return 0; 277 } 278 200 279 /** Updates the datetime of a mrb_time based on it's timezone and 201 seconds setting. Returns self on success, NULL of failure. */ 280 seconds setting. Returns self on success, NULL of failure. 281 if `dealloc` is set `true`, it frees `self` on error. */ 202 282 static struct mrb_time* 203 time_update_datetime(mrb_state *mrb, struct mrb_time *self )283 time_update_datetime(mrb_state *mrb, struct mrb_time *self, int dealloc) 204 284 { 205 285 struct tm *aid; 286 time_t t = self->sec; 206 287 207 288 if (self->timezone == MRB_TIMEZONE_UTC) { 208 aid = gmtime_r(& self->sec, &self->datetime);289 aid = gmtime_r(&t, &self->datetime); 209 290 } 210 291 else { 211 aid = localtime_r(& self->sec, &self->datetime);292 aid = localtime_r(&t, &self->datetime); 212 293 } 213 294 if (!aid) { 214 mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, (mrb_float)self->sec)); 295 mrb_sec sec = (mrb_sec)t; 296 297 if (dealloc) mrb_free(mrb, self); 298 mrb_raisef(mrb, E_ARGUMENT_ERROR, "%v out of Time range", mrb_sec_value(mrb, sec)); 215 299 /* not reached */ 216 300 return NULL; … … 229 313 } 230 314 231 void mrb_check_num_exact(mrb_state *mrb, mrb_float num);232 233 315 /* Allocates a mrb_time object and initializes it. */ 234 316 static struct mrb_time* 235 time_alloc(mrb_state *mrb, double sec, double usec, enum mrb_timezone timezone) 236 { 237 struct mrb_time *tm; 238 time_t tsec = 0; 239 240 mrb_check_num_exact(mrb, (mrb_float)sec); 241 mrb_check_num_exact(mrb, (mrb_float)usec); 242 243 if (sizeof(time_t) == 4 && (sec > (double)INT32_MAX || (double)INT32_MIN > sec)) { 244 goto out_of_range; 245 } 246 if (sizeof(time_t) == 8 && (sec > (double)INT64_MAX || (double)INT64_MIN > sec)) { 247 goto out_of_range; 248 } 249 tsec = (time_t)sec; 250 if ((sec > 0 && tsec < 0) || (sec < 0 && (double)tsec > sec)) { 251 out_of_range: 252 mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, sec)); 253 } 317 time_alloc_time(mrb_state *mrb, time_t sec, time_t usec, enum mrb_timezone timezone) 318 { 319 struct mrb_time *tm; 320 254 321 tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(struct mrb_time)); 255 tm->sec = tsec;256 tm->usec = (time_t)llround((sec - tm->sec) * 1.0e6 + usec);322 tm->sec = sec; 323 tm->usec = usec; 257 324 if (tm->usec < 0) { 258 long sec2 = (long)NDIV( usec,1000000); /* negative div */325 long sec2 = (long)NDIV(tm->usec,1000000); /* negative div */ 259 326 tm->usec -= sec2 * 1000000; 260 327 tm->sec += sec2; 261 328 } 262 329 else if (tm->usec >= 1000000) { 263 long sec2 = (long)( usec / 1000000);330 long sec2 = (long)(tm->usec / 1000000); 264 331 tm->usec -= sec2 * 1000000; 265 332 tm->sec += sec2; 266 333 } 267 334 tm->timezone = timezone; 268 time_update_datetime(mrb, tm );335 time_update_datetime(mrb, tm, TRUE); 269 336 270 337 return tm; 271 338 } 272 339 273 static mrb_value 274 mrb_time_make(mrb_state *mrb, struct RClass *c, double sec, double usec, enum mrb_timezone timezone) 340 static struct mrb_time* 341 time_alloc(mrb_state *mrb, mrb_value sec, mrb_value usec, enum mrb_timezone timezone) 342 { 343 time_t tsec, tusec; 344 345 tsec = mrb_to_time_t(mrb, sec, &tusec); 346 tusec += mrb_to_time_t(mrb, usec, NULL); 347 348 return time_alloc_time(mrb, tsec, tusec, timezone); 349 } 350 351 static mrb_value 352 mrb_time_make_time(mrb_state *mrb, struct RClass *c, time_t sec, time_t usec, enum mrb_timezone timezone) 353 { 354 return mrb_time_wrap(mrb, c, time_alloc_time(mrb, sec, usec, timezone)); 355 } 356 357 static mrb_value 358 mrb_time_make(mrb_state *mrb, struct RClass *c, mrb_value sec, mrb_value usec, enum mrb_timezone timezone) 275 359 { 276 360 return mrb_time_wrap(mrb, c, time_alloc(mrb, sec, usec, timezone)); … … 280 364 current_mrb_time(mrb_state *mrb) 281 365 { 282 struct mrb_time *tm; 283 284 tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm)); 285 #if defined(TIME_UTC) 366 struct mrb_time tmzero = {0}; 367 struct mrb_time *tm; 368 time_t sec, usec; 369 370 #if defined(TIME_UTC) && !defined(__ANDROID__) 286 371 { 287 372 struct timespec ts; 288 373 if (timespec_get(&ts, TIME_UTC) == 0) { 289 mrb_free(mrb, tm);290 374 mrb_raise(mrb, E_RUNTIME_ERROR, "timespec_get() failed for unknown reasons"); 291 375 } 292 tm->sec = ts.tv_sec;293 tm->usec = ts.tv_nsec / 1000;376 sec = ts.tv_sec; 377 usec = ts.tv_nsec / 1000; 294 378 } 295 379 #elif defined(NO_GETTIMEOFDAY) … … 297 381 static time_t last_sec = 0, last_usec = 0; 298 382 299 tm->sec= time(NULL);300 if ( tm->sec != last_sec) {301 last_sec = tm->sec;383 sec = time(NULL); 384 if (sec != last_sec) { 385 last_sec = sec; 302 386 last_usec = 0; 303 387 } … … 306 390 last_usec += 1; 307 391 } 308 tm->usec = last_usec;392 usec = last_usec; 309 393 } 310 394 #else … … 313 397 314 398 gettimeofday(&tv, NULL); 315 tm->sec = tv.tv_sec; 316 tm->usec = tv.tv_usec; 317 } 318 #endif 399 sec = tv.tv_sec; 400 usec = tv.tv_usec; 401 } 402 #endif 403 tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm)); 404 *tm = tmzero; 405 tm->sec = sec; tm->usec = usec; 319 406 tm->timezone = MRB_TIMEZONE_LOCAL; 320 time_update_datetime(mrb, tm );407 time_update_datetime(mrb, tm, TRUE); 321 408 322 409 return tm; … … 328 415 { 329 416 return mrb_time_wrap(mrb, mrb_class_ptr(self), current_mrb_time(mrb)); 417 } 418 419 MRB_API mrb_value 420 mrb_time_at(mrb_state *mrb, time_t sec, time_t usec, enum mrb_timezone zone) 421 { 422 return mrb_time_make_time(mrb, mrb_class_get(mrb, "Time"), sec, usec, zone); 330 423 } 331 424 … … 333 426 /* Creates an instance of time at the given time in seconds, etc. */ 334 427 static mrb_value 335 mrb_time_at(mrb_state *mrb, mrb_value self) 336 { 337 mrb_float f, f2 = 0; 338 339 mrb_get_args(mrb, "f|f", &f, &f2); 340 return mrb_time_make(mrb, mrb_class_ptr(self), f, f2, MRB_TIMEZONE_LOCAL); 428 mrb_time_at_m(mrb_state *mrb, mrb_value self) 429 { 430 mrb_value sec; 431 mrb_value usec = mrb_fixnum_value(0); 432 433 mrb_get_args(mrb, "o|o", &sec, &usec); 434 435 return mrb_time_make(mrb, mrb_class_ptr(self), sec, usec, MRB_TIMEZONE_LOCAL); 341 436 } 342 437 … … 375 470 } 376 471 377 return time_alloc (mrb, (double)nowsecs, ausec, timezone);472 return time_alloc_time(mrb, nowsecs, ausec, timezone); 378 473 } 379 474 … … 461 556 mrb_time_plus(mrb_state *mrb, mrb_value self) 462 557 { 463 mrb_float f; 464 struct mrb_time *tm; 465 466 mrb_get_args(mrb, "f", &f); 467 tm = time_get_ptr(mrb, self); 468 return mrb_time_make(mrb, mrb_obj_class(mrb, self), (double)tm->sec+f, (double)tm->usec, tm->timezone); 558 mrb_value o; 559 struct mrb_time *tm; 560 time_t sec, usec; 561 562 mrb_get_args(mrb, "o", &o); 563 tm = time_get_ptr(mrb, self); 564 sec = mrb_to_time_t(mrb, o, &usec); 565 return mrb_time_make_time(mrb, mrb_obj_class(mrb, self), tm->sec+sec, tm->usec+usec, tm->timezone); 469 566 } 470 567 … … 472 569 mrb_time_minus(mrb_state *mrb, mrb_value self) 473 570 { 474 mrb_float f;475 571 mrb_value other; 476 572 struct mrb_time *tm, *tm2; … … 480 576 tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time); 481 577 if (tm2) { 482 f = (mrb_float)(tm->sec - tm2->sec) 483 + (mrb_float)(tm->usec - tm2->usec) / 1.0e6; 578 #ifndef MRB_WITHOUT_FLOAT 579 mrb_float f; 580 f = (mrb_sec)(tm->sec - tm2->sec) 581 + (mrb_sec)(tm->usec - tm2->usec) / 1.0e6; 484 582 return mrb_float_value(mrb, f); 583 #else 584 mrb_int f; 585 f = tm->sec - tm2->sec; 586 if (tm->usec < tm2->usec) f--; 587 return mrb_fixnum_value(f); 588 #endif 485 589 } 486 590 else { 487 mrb_get_args(mrb, "f", &f); 488 return mrb_time_make(mrb, mrb_obj_class(mrb, self), (double)tm->sec-f, (double)tm->usec, tm->timezone); 591 time_t sec, usec; 592 sec = mrb_to_time_t(mrb, other, &usec); 593 return mrb_time_make_time(mrb, mrb_obj_class(mrb, self), tm->sec-sec, tm->usec-usec, tm->timezone); 489 594 } 490 595 } … … 547 652 int len; 548 653 549 #if defined( DISABLE_STDIO)654 #if defined(MRB_DISABLE_STDIO) 550 655 char *s; 551 656 # ifdef NO_ASCTIME_R … … 559 664 char buf[256]; 560 665 561 len = snprintf(buf, sizeof(buf), "%s %s % 02d %02d:%02d:%02d %s%d",666 len = snprintf(buf, sizeof(buf), "%s %s %2d %02d:%02d:%02d %.4d", 562 667 wday_names[d->tm_wday], mon_names[d->tm_mon], d->tm_mday, 563 668 d->tm_hour, d->tm_min, d->tm_sec, 564 tm->timezone == MRB_TIMEZONE_UTC ? "UTC " : "",565 669 d->tm_year + 1900); 566 670 #endif … … 603 707 *tm2 = *tm; 604 708 tm2->timezone = MRB_TIMEZONE_UTC; 605 time_update_datetime(mrb, tm2 );709 time_update_datetime(mrb, tm2, TRUE); 606 710 return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2); 607 711 } … … 618 722 *tm2 = *tm; 619 723 tm2->timezone = MRB_TIMEZONE_LOCAL; 620 time_update_datetime(mrb, tm2 );724 time_update_datetime(mrb, tm2, TRUE); 621 725 return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2); 622 726 } … … 640 744 mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0, 641 745 amin = 0, asec = 0, ausec = 0; 642 int n;746 mrb_int n; 643 747 struct mrb_time *tm; 644 748 … … 696 800 tm = time_get_ptr(mrb, self); 697 801 tm->timezone = MRB_TIMEZONE_LOCAL; 698 time_update_datetime(mrb, tm );802 time_update_datetime(mrb, tm, FALSE); 699 803 return self; 700 804 } … … 744 848 } 745 849 746 850 #ifndef MRB_WITHOUT_FLOAT 747 851 /* 15.2.19.7.24 */ 748 852 /* Returns a Float with the time since the epoch in seconds. */ … … 755 859 return mrb_float_value(mrb, (mrb_float)tm->sec + (mrb_float)tm->usec/1.0e6); 756 860 } 861 #endif 757 862 758 863 /* 15.2.19.7.25 */ 759 /* Returns a Fixnumwith the time since the epoch in seconds. */864 /* Returns an Integer with the time since the epoch in seconds. */ 760 865 static mrb_value 761 866 mrb_time_to_i(mrb_state *mrb, mrb_value self) … … 764 869 765 870 tm = time_get_ptr(mrb, self); 766 if (tm->sec > MRB_INT_MAX || tm->sec < MRB_INT_MIN) { 871 #ifndef MRB_WITHOUT_FLOAT 872 if (!fixable_time_t_p(tm->sec)) { 767 873 return mrb_float_value(mrb, (mrb_float)tm->sec); 768 874 } 875 #endif 769 876 return mrb_fixnum_value((mrb_int)tm->sec); 770 877 } 771 878 772 879 /* 15.2.19.7.26 */ 773 /* Returns a Floatwith the time since the epoch in microseconds. */880 /* Returns an Integer with the time since the epoch in microseconds. */ 774 881 static mrb_value 775 882 mrb_time_usec(mrb_state *mrb, mrb_value self) … … 778 885 779 886 tm = time_get_ptr(mrb, self); 780 if (tm->usec > MRB_INT_MAX || tm->usec < MRB_INT_MIN) { 887 #ifndef MRB_WITHOUT_FLOAT 888 if (!fixable_time_t_p(tm->usec)) { 781 889 return mrb_float_value(mrb, (mrb_float)tm->usec); 782 890 } 891 #endif 783 892 return mrb_fixnum_value((mrb_int)tm->usec); 784 893 } … … 793 902 tm = time_get_ptr(mrb, self); 794 903 tm->timezone = MRB_TIMEZONE_UTC; 795 time_update_datetime(mrb, tm );904 time_update_datetime(mrb, tm, FALSE); 796 905 return self; 797 906 } … … 808 917 } 809 918 919 static size_t 920 time_to_s_utc(mrb_state *mrb, struct mrb_time *tm, char *buf, size_t buf_len) 921 { 922 return strftime(buf, buf_len, TO_S_FMT "UTC", &tm->datetime); 923 } 924 925 static size_t 926 time_to_s_local(mrb_state *mrb, struct mrb_time *tm, char *buf, size_t buf_len) 927 { 928 #if defined(_MSC_VER) && _MSC_VER < 1900 || defined(__MINGW64__) || defined(__MINGW32__) 929 struct tm datetime = {0}; 930 time_t utc_sec = timegm(&tm->datetime); 931 size_t len; 932 int offset; 933 934 if (utc_sec == (time_t)-1) { 935 mrb_raise(mrb, E_ARGUMENT_ERROR, "Not a valid time."); 936 } 937 offset = abs((int)(utc_sec - tm->sec) / 60); 938 datetime.tm_year = 100; 939 datetime.tm_hour = offset / 60; 940 datetime.tm_min = offset % 60; 941 len = strftime(buf, buf_len, TO_S_FMT, &tm->datetime); 942 buf[len++] = utc_sec < tm->sec ? '-' : '+'; 943 944 return len + strftime(buf + len, buf_len - len, "%H%M", &datetime); 945 #else 946 return strftime(buf, buf_len, TO_S_FMT "%z", &tm->datetime); 947 #endif 948 } 949 950 static mrb_value 951 mrb_time_to_s(mrb_state *mrb, mrb_value self) 952 { 953 char buf[64]; 954 struct mrb_time *tm = time_get_ptr(mrb, self); 955 mrb_bool utc = tm->timezone == MRB_TIMEZONE_UTC; 956 size_t len = (utc ? time_to_s_utc : time_to_s_local)(mrb, tm, buf, sizeof(buf)); 957 return mrb_str_new(mrb, buf, len); 958 } 810 959 811 960 void … … 817 966 MRB_SET_INSTANCE_TT(tc, MRB_TT_DATA); 818 967 mrb_include_module(mrb, tc, mrb_module_get(mrb, "Comparable")); 819 mrb_define_class_method(mrb, tc, "at", mrb_time_at , MRB_ARGS_ARG(1, 1)); /* 15.2.19.6.1 */968 mrb_define_class_method(mrb, tc, "at", mrb_time_at_m, MRB_ARGS_ARG(1, 1)); /* 15.2.19.6.1 */ 820 969 mrb_define_class_method(mrb, tc, "gm", mrb_time_gm, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.2 */ 821 970 mrb_define_class_method(mrb, tc, "local", mrb_time_local, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.3 */ … … 828 977 mrb_define_method(mrb, tc, "+" , mrb_time_plus , MRB_ARGS_REQ(1)); /* 15.2.19.7.2 */ 829 978 mrb_define_method(mrb, tc, "-" , mrb_time_minus , MRB_ARGS_REQ(1)); /* 15.2.19.7.3 */ 830 mrb_define_method(mrb, tc, "to_s" , mrb_time_ asctime, MRB_ARGS_NONE());831 mrb_define_method(mrb, tc, "inspect", mrb_time_ asctime, MRB_ARGS_NONE());979 mrb_define_method(mrb, tc, "to_s" , mrb_time_to_s , MRB_ARGS_NONE()); 980 mrb_define_method(mrb, tc, "inspect", mrb_time_to_s , MRB_ARGS_NONE()); 832 981 mrb_define_method(mrb, tc, "asctime", mrb_time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.4 */ 833 982 mrb_define_method(mrb, tc, "ctime" , mrb_time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.5 */ … … 849 998 mrb_define_method(mrb, tc, "sec" , mrb_time_sec, MRB_ARGS_NONE()); /* 15.2.19.7.23 */ 850 999 mrb_define_method(mrb, tc, "to_i", mrb_time_to_i, MRB_ARGS_NONE()); /* 15.2.19.7.25 */ 1000 #ifndef MRB_WITHOUT_FLOAT 851 1001 mrb_define_method(mrb, tc, "to_f", mrb_time_to_f, MRB_ARGS_NONE()); /* 15.2.19.7.24 */ 1002 #endif 852 1003 mrb_define_method(mrb, tc, "usec", mrb_time_usec, MRB_ARGS_NONE()); /* 15.2.19.7.26 */ 853 1004 mrb_define_method(mrb, tc, "utc" , mrb_time_utc, MRB_ARGS_NONE()); /* 15.2.19.7.27 */ -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-time/test/time.rb
r331 r439 3 3 4 4 assert('Time.new', '15.2.3.3.3') do 5 Time.new.class == Time5 assert_equal(Time, Time.new.class) 6 6 end 7 7 8 8 assert('Time', '15.2.19') do 9 Time.class == Class9 assert_equal(Class, Time.class) 10 10 end 11 11 … … 22 22 23 23 assert('Time.gm', '15.2.19.6.2') do 24 Time.gm(2012, 12, 23) 24 t = Time.gm(2012, 9, 23) 25 assert_operator(2012, :eql?, t.year) 26 assert_operator( 9, :eql?, t.month) 27 assert_operator( 23, :eql?, t.day) 28 assert_operator( 0, :eql?, t.hour) 29 assert_operator( 0, :eql?, t.min) 30 assert_operator( 0, :eql?, t.sec) 31 assert_operator( 0, :eql?, t.usec) 25 32 end 26 33 27 34 assert('Time.local', '15.2.19.6.3') do 28 Time.local(2012, 12, 23) 35 t = Time.local(2014, 12, 27, 18) 36 assert_operator(2014, :eql?, t.year) 37 assert_operator( 12, :eql?, t.month) 38 assert_operator( 27, :eql?, t.day) 39 assert_operator( 18, :eql?, t.hour) 40 assert_operator( 0, :eql?, t.min) 41 assert_operator( 0, :eql?, t.sec) 42 assert_operator( 0, :eql?, t.usec) 29 43 end 30 44 31 45 assert('Time.mktime', '15.2.19.6.4') do 32 Time.mktime(2012, 12, 23) 46 t = Time.mktime(2013, 10, 4, 6, 15, 58, 3485) 47 assert_operator(2013, :eql?, t.year) 48 assert_operator( 10, :eql?, t.month) 49 assert_operator( 4, :eql?, t.day) 50 assert_operator( 6, :eql?, t.hour) 51 assert_operator( 15, :eql?, t.min) 52 assert_operator( 58, :eql?, t.sec) 53 assert_operator(3485, :eql?, t.usec) 33 54 end 34 55 35 56 assert('Time.now', '15.2.19.6.5') do 36 Time.now.class == Time57 assert_equal(Time, Time.now.class) 37 58 end 38 59 39 60 assert('Time.utc', '15.2.19.6.6') do 40 Time.utc(2012, 12, 23) 61 t = Time.utc(2034) 62 assert_operator(2034, :eql?, t.year) 63 assert_operator( 1, :eql?, t.month) 64 assert_operator( 1, :eql?, t.day) 65 assert_operator( 0, :eql?, t.hour) 66 assert_operator( 0, :eql?, t.min) 67 assert_operator( 0, :eql?, t.sec) 68 assert_operator( 0, :eql?, t.usec) 41 69 end 42 70 … … 45 73 t2 = t1.+(60) 46 74 47 assert_equal( t2.utc.asctime, "Sun Mar 13 07:07:40 UTC 2011")75 assert_equal("Sun Mar 13 07:07:40 2011", t2.utc.asctime) 48 76 49 77 assert_raise(FloatDomainError) { Time.at(0) + Float::NAN } … … 56 84 t2 = t1.-(60) 57 85 58 assert_equal( t2.utc.asctime, "Sun Mar 13 07:05:40 UTC 2011")86 assert_equal("Sun Mar 13 07:05:40 2011", t2.utc.asctime) 59 87 60 88 assert_raise(FloatDomainError) { Time.at(0) - Float::NAN } … … 68 96 t3 = Time.at(1500000000.0) 69 97 70 t2.<=>(t1) == 1 and71 t2.<=>(t2) == 0 and72 t2.<=>(t3) == -1 and73 t2.<=>(nil) == nil98 assert_equal(1, t2 <=> t1) 99 assert_equal(0, t2 <=> t2) 100 assert_equal(-1, t2 <=> t3) 101 assert_nil(t2 <=> nil) 74 102 end 75 103 76 104 assert('Time#asctime', '15.2.19.7.4') do 77 Time.at(1300000000.0).utc.asctime == "Sun Mar 13 07:06:40 UTC 2011"105 assert_equal("Thu Mar 4 05:06:07 1982", Time.gm(1982,3,4,5,6,7).asctime) 78 106 end 79 107 80 108 assert('Time#ctime', '15.2.19.7.5') do 81 Time.at(1300000000.0).utc.ctime == "Sun Mar 13 07:06:40 UTC 2011"109 assert_equal("Thu Oct 24 15:26:47 2013", Time.gm(2013,10,24,15,26,47).ctime) 82 110 end 83 111 84 112 assert('Time#day', '15.2.19.7.6') do 85 Time.gm(2012, 12, 23).day == 23113 assert_equal(23, Time.gm(2012, 12, 23).day) 86 114 end 87 115 88 116 assert('Time#dst?', '15.2.19.7.7') do 89 not Time.gm(2012, 12, 23).utc.dst?117 assert_not_predicate(Time.gm(2012, 12, 23).utc, :dst?) 90 118 end 91 119 92 120 assert('Time#getgm', '15.2.19.7.8') do 93 Time.at(1300000000.0).getgm.asctime == "Sun Mar 13 07:06:40 UTC 2011"121 assert_equal("Sun Mar 13 07:06:40 2011", Time.at(1300000000.0).getgm.asctime) 94 122 end 95 123 … … 99 127 t3 = t1.getlocal 100 128 101 t1 == t3 and t3 == t2.getlocal 129 assert_equal(t1, t3) 130 assert_equal(t3, t2.getlocal) 102 131 end 103 132 104 133 assert('Time#getutc', '15.2.19.7.10') do 105 Time.at(1300000000.0).getutc.asctime == "Sun Mar 13 07:06:40 UTC 2011"134 assert_equal("Sun Mar 13 07:06:40 2011", Time.at(1300000000.0).getutc.asctime) 106 135 end 107 136 108 137 assert('Time#gmt?', '15.2.19.7.11') do 109 Time.at(1300000000.0).utc.gmt?138 assert_predicate(Time.at(1300000000.0).utc, :gmt?) 110 139 end 111 140 … … 114 143 115 144 assert('Time#gmtime', '15.2.19.7.13') do 116 Time.at(1300000000.0).gmtime 145 t = Time.now 146 assert_predicate(t.gmtime, :gmt?) 147 assert_predicate(t, :gmt?) 117 148 end 118 149 … … 121 152 122 153 assert('Time#hour', '15.2.19.7.15') do 123 Time.gm(2012, 12, 23, 7, 6).hour == 7154 assert_equal(7, Time.gm(2012, 12, 23, 7, 6).hour) 124 155 end 125 156 … … 128 159 129 160 assert('Time#initialize_copy', '15.2.19.7.17') do 130 t ime_tmp_2= Time.at(7.0e6)131 time_tmp_2.clone == time_tmp_2161 t = Time.at(7.0e6) 162 assert_equal(t, t.clone) 132 163 end 133 164 134 165 assert('Time#localtime', '15.2.19.7.18') do 135 t1 = Time.at(1300000000.0) 136 t2 = Time.at(1300000000.0) 137 138 t1.localtime 139 t1 == t2.getlocal 166 t1 = Time.utc(2014, 5 ,6) 167 t2 = Time.utc(2014, 5 ,6) 168 t3 = t2.getlocal 169 170 assert_equal(t3, t1.localtime) 171 assert_equal(t3, t1) 140 172 end 141 173 142 174 assert('Time#mday', '15.2.19.7.19') do 143 Time.gm(2012, 12, 23).mday == 23175 assert_equal(23, Time.gm(2012, 12, 23).mday) 144 176 end 145 177 146 178 assert('Time#min', '15.2.19.7.20') do 147 Time.gm(2012, 12, 23, 7, 6).min == 6179 assert_equal(6, Time.gm(2012, 12, 23, 7, 6).min) 148 180 end 149 181 150 182 assert('Time#mon', '15.2.19.7.21') do 151 Time.gm(2012, 12, 23).mon == 12183 assert_equal(12, Time.gm(2012, 12, 23).mon) 152 184 end 153 185 154 186 assert('Time#month', '15.2.19.7.22') do 155 Time.gm(2012, 12, 23).month == 12187 assert_equal(12, Time.gm(2012, 12, 23).month) 156 188 end 157 189 158 190 assert('Times#sec', '15.2.19.7.23') do 159 Time.gm(2012, 12, 23, 7, 6, 40).sec == 40191 assert_equal(40, Time.gm(2012, 12, 23, 7, 6, 40).sec) 160 192 end 161 193 162 194 assert('Time#to_f', '15.2.19.7.24') do 163 Time.at(1300000000.0).to_f == 1300000000.0195 assert_operator(2.0, :eql?, Time.at(2).to_f) 164 196 end 165 197 166 198 assert('Time#to_i', '15.2.19.7.25') do 167 Time.at(1300000000.0).to_i == 1300000000199 assert_operator(2, :eql?, Time.at(2.0).to_i) 168 200 end 169 201 170 202 assert('Time#usec', '15.2.19.7.26') do 171 Time.at(1300000000.0).usec == 0203 assert_equal(0, Time.at(1300000000.0).usec) 172 204 end 173 205 174 206 assert('Time#utc', '15.2.19.7.27') do 175 Time.at(1300000000.0).utc 207 t = Time.now 208 assert_predicate(t.utc, :gmt?) 209 assert_predicate(t, :gmt?) 176 210 end 177 211 178 212 assert('Time#utc?', '15.2.19.7.28') do 179 Time.at(1300000000.0).utc.utc?213 assert_predicate(Time.at(1300000000.0).utc, :utc?) 180 214 end 181 215 … … 184 218 185 219 assert('Time#wday', '15.2.19.7.30') do 186 Time.gm(2012, 12, 23).wday == 0220 assert_equal(0, Time.gm(2012, 12, 23).wday) 187 221 end 188 222 189 223 assert('Time#yday', '15.2.19.7.31') do 190 Time.gm(2012, 12, 23).yday == 358224 assert_equal(358, Time.gm(2012, 12, 23).yday) 191 225 end 192 226 193 227 assert('Time#year', '15.2.19.7.32') do 194 Time.gm(2012, 12, 23).year == 2012228 assert_equal(2012, Time.gm(2012, 12, 23).year) 195 229 end 196 230 197 231 assert('Time#zone', '15.2.19.7.33') do 198 Time.at(1300000000.0).utc.zone == 'UTC'232 assert_equal('UTC', Time.at(1300000000.0).utc.zone) 199 233 end 200 234 … … 202 236 203 237 assert('Time#to_s') do 204 Time.at(1300000000.0).utc.to_s == "Sun Mar 13 07:06:40 UTC 2011"238 assert_equal("2003-04-05 06:07:08 UTC", Time.gm(2003,4,5,6,7,8,9).to_s) 205 239 end 206 240 207 241 assert('Time#inspect') do 208 Time.at(1300000000.0).utc.inspect == "Sun Mar 13 07:06:40 UTC 2011" 242 assert_match("2013-10-28 16:27:48 [+-][0-9][0-9][0-9][0-9]", 243 Time.local(2013,10,28,16,27,48).inspect) 209 244 end 210 245 … … 225 260 t += 0.0005 226 261 end 227 t.usec == 0 228 end 262 assert_equal(0, t.usec) 263 end 264 265 assert('Time.gm with Dec 31 23:59:59 1969 raise ArgumentError') do 266 assert_raise(ArgumentError) {Time.gm(1969, 12, 31, 23, 59, 59)} 267 end -
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-toplevel-ext/test/toplevel.rb
r321 r439 17 17 self.include ToplevelTestModule2, ToplevelTestModule1 18 18 19 assert_true self.class. included_modules.include?( ToplevelTestModule1 )20 assert_true self.class. included_modules.include?( ToplevelTestModule2 )19 assert_true self.class.ancestors.include?( ToplevelTestModule1 ) 20 assert_true self.class.ancestors.include?( ToplevelTestModule2 ) 21 21 assert_equal :foo, method_foo 22 22 assert_equal :bar2, CONST_BAR
Note:
See TracChangeset
for help on using the changeset viewer.