Ticket #71: for-expr-numeric.patch
File for-expr-numeric.patch, 8.5 KB (added by hopscc, 16 years ago) |
---|
-
Source/Expr.cobra
865 865 var _what as Expr 866 866 var _whereExpr as Expr? 867 867 var _getExpr as Expr 868 var _start as Expr? 869 var _stop as Expr? 870 var _step as Expr? 868 871 869 def init(token as IToken, nameExpr as NameExpr, what as Expr, whereExpr as Expr?, getExpr as Expr) 872 def init(token as IToken, nameExpr as NameExpr, what as Expr, stopExpr as Expr?, 873 stepExpr as Expr?, whereExpr as Expr?, getExpr as Expr) 870 874 base.init(token) 871 875 _nameExpr = nameExpr 872 876 _what = what 877 _stop = stopExpr 878 _step = stepExpr 873 879 _whereExpr = whereExpr 874 880 _getExpr = getExpr 875 881 … … 880 886 .addField('what', _what) 881 887 .addField('whereExpr', _whereExpr) 882 888 .addField('getExpr', _getExpr) 889 .addField('start', _start) 890 .addField('stop', _stop) 891 .addField('step', _step) 883 892 884 893 get willChangeVar as bool is override 885 894 # TODO: ack. kind of weird. if the variable is a new one and its not read afterwards (without first being set) then no side effects. … … 892 901 base._bindImp 893 902 _what.bindImp # bind first because it may be needed for type inference 894 903 whatType = _what.type to ! 895 if not whatType.isDescendantOf(.compiler.enumerableType) and not whatType.isSequenceLike # TODO: can probably drop .isSequenceLike 904 if whatType inherits AnyIntType 905 if _stop 906 _start = _what 907 _stop.bindImp 908 else 909 _start = IntegerLit(.token.copy('INTEGER_LIT', '0'), 0).bindImp 910 _stop = _what 911 if not _step 912 _step = IntegerLit(.token.copy('INTEGER_LIT', '1'), 1) 913 _step.bindImp 914 else if not whatType.isDescendantOf(.compiler.enumerableType) and not whatType.isSequenceLike # TODO: can probably drop .isSequenceLike 896 915 .throwError('Cannot enumerate values of type "[whatType.name]". You can enumerate anything enumerable (IEnumerable, IList, arrays, strings, etc.).') 897 916 _var = .bindVar(_nameExpr) 898 917 if _nameExpr.definition … … 913 932 914 933 def inferredType as IType? is override 915 934 assert _what.type 916 return _what.type.innerType935 return if(_what.type inherits AnyIntType, _what.type, _what.type.innerType) 917 936 918 937 919 938 class IdentifierExpr -
Source/Cobra.Lang/Native.cs
774 774 return results; 775 775 } 776 776 777 /* Numeric forExpr */ 778 static public List<int> For<TIn, TOut>(int start, int stop, int step, ForGet<int, int> forGet) { 779 if ((step > 0 && start > stop) || 780 (step < 0 && start < stop) || step == 0) 781 throw new IndexOutOfRangeException(string.Format("ForExpr will never terminate; start={0} stop={1} step={2}",start, stop,step)); 782 List<int> results = new List<int>(); 783 for ( int item = start; 784 (step>0 && item < stop) || (step<0 && item > stop); 785 item += step) 786 results.Add(forGet(item)); 787 return results; 788 } 789 static public List<int> For<TIn, TOut>( int start, int stop, int step, ForWhereGet<int, int> forWhereGet) { 790 if ((step > 0 && start > stop) || 791 (step < 0 && start < stop) || step == 0) 792 throw new IndexOutOfRangeException(string.Format("ForExpr will never terminate; start={0} stop={1} step={2}",start, stop,step)); 793 List<int> results = new List<int>(); 794 for ( int item = start; 795 (step>0 && item < stop) || (step<0 && item > stop); 796 item += step) { 797 int value; 798 if (forWhereGet(item, out value)) 799 results.Add(value); 800 } 801 return results; 802 } 803 777 804 static private void ProcessGetSliceArgs(int count, ref int? start, ref int? stop, ref int? step) { 778 805 if (start==null) 779 806 start = 0; -
Source/BackEndClr/SharpGenerator.cobra
3110 3110 def writeSharpDef(sw as SharpWriter, parens as bool) is override 3111 3111 # C#: CobraImp.For(stuff, delegate(x as int) { return x*x }) 3112 3112 # C#: CobraImp.For(stuff, delegate(x as int) { if (x<0) return x*x; }) 3113 inType = _what.type.innerType3113 inType = .inferredType # _what.type.innerType 3114 3114 outType = _getExpr.type 3115 3115 sw.write('CobraImp.For<[inType.sharpRef],[outType.sharpRef]>(') 3116 _what.writeSharpDef(sw, false) 3116 if _stop 3117 # C#: Numeric For Expr CobraImp.For(start, stop, step, delegate(x as int) { return x*x; }) 3118 _start.writeSharpDef(sw, false) 3119 sw.write(', ') 3120 _stop.writeSharpDef(sw, false) 3121 sw.write(', ') 3122 _step.writeSharpDef(sw, false) 3123 else 3124 _what.writeSharpDef(sw, false) 3117 3125 sw.write(', ') 3118 3126 helperName = '_lh_for_[_var.name]_[_varNumber]' 3119 3127 if _whereExpr is nil -
Source/CobraParser.cobra
2944 2944 # throw FallThroughException(peek) # make C# code flow analysis happy 2945 2945 .expect('IN') 2946 2946 what = .expression 2947 if .optional('COLON') 2948 # for x in start : stop ... 2949 # for x in start : stop : step .... 2950 stopExpr = .expression 2951 if .optional('COLON') 2952 stepExpr = .expression 2947 2953 if .optional('WHERE') 2948 2954 whereExpr as Expr? = .expression 2949 2955 if .optional('GET') … … 2953 2959 else 2954 2960 .expect('GET') 2955 2961 getExpr = .expression 2956 return ForExpr(token, nameExpr, what, whereExpr, getExpr)2962 return ForExpr(token, nameExpr, what, stopExpr, stepExpr, whereExpr, getExpr) 2957 2963 2958 2964 def identifierExpr as Expr 2959 2965 """ -
Tests/110-basics-two/600-functional/110-for-expr-enumerable.cobra
1 # for expression over enumerables 2 class ForExprEnum 3 def main is shared 4 5 a = for i in [1,2,3] get i*10 6 assert a == [10, 20, 30] 7 #print a 8 9 b = for j in 'aeiou' get j 10 assert b == [c'a', c'e', c'i', c'o', c'u'] 11 #print b 12 13 c = ['how', 'now', 'brown', 'cow'] 14 d = for k in c where k.endsWith('ow') get k 15 assert d == ['how', 'now', 'cow'] 16 17 d = for k in c where not k.endsWith('ow') get k 18 assert d == ['brown'] 19 -
Tests/110-basics-two/600-functional/111-for-expr-numeric.cobra
1 # for expression over numeric range 2 class ForExprNum 3 def main is shared 4 5 a = for i in [1,2,3] get i*10 6 assert a == [10,20,30] 7 #print a 8 9 a = for i in 10 get i 10 assert a == [0,1,2,3,4,5,6,7,8,9] 11 #print a 12 13 a = for i in 10 where i>5 get i 14 assert a == [6,7,8,9] 15 #print a 16 17 18 max = 20 19 am = for i in max where i>15 get i 20 assert am == [16,17,18,19] 21 22 b = for i in 3:6 get i 23 assert b == [3,4,5] 24 #print b 25 26 b = for i in 3:6 where i>=4 get i+1 27 assert b == [5,6] 28 #print b 29 30 31 c = for i in 3:6:2 get i 32 assert c == [3,5] 33 #print c 34 35 c = for i in 3:8:2 where i>=4 get i+1 36 assert c == [6,8] 37 #print c 38 39 40 c = for i in 3:8:5 where i>=4 get i-10 41 assert c == [] 42 #print c 43 44 c = for i in 8:5:-1 get i 45 assert c == [8,7,6] 46 #print c 47 48 c = for i in 8:5:-2 get i 49 assert c == [8,6] 50 51 for i in 8:5:-1 52 print i 53 for i in 8:5:-2 54 print i 55 56 # Non terminating 57 expect IndexOutOfRangeException 58 d = for j in 8:5 get i 59 CobraCore.noOp(d) 60 61 # Non terminating 62 expect IndexOutOfRangeException 63 d = for j in 5:8:-1 get i 64 CobraCore.noOp(d) 65 -
Developer/IntermediateReleaseNotes.text
235 235 * Fixed: Cannot use `for` expressions on non-generic enumerables. ticket:85 236 236 237 237 * Fixed: Cannot `listen` to an event when the `ref`ed method is an overload. 238 239 * Fixed: for-expr enumerate int and slice-like range: ticket:71