Changeset 1564

Show
Ignore:
Timestamp:
07/31/08 05:41:13 (4 months ago)
Author:
Chuck.Esterbrook
Message:

Added new all and any unary operators that take something enumerable (such as a list, set or generator) and return a boolean (true or false) indicating if all or any of the elements are true.

Location:
cobra/trunk
Files:
1 added
5 modified

Legend:

Unmodified
Added
Removed
  • cobra/trunk/Developer/IntermediateReleaseNotes.text

    r1560 r1564  
    77* Add support for specifying unsigned integers as Hex literals 
    88    e.g. 0x7f  0x7f_8   0x7Fu16  0x7F_u32 
     9 
     10* Added new `all` and `any` unary operators that take something enumerable (such as a list, set or generator) and return a boolean (true or false) indicating if all or any of the elements are true. These operators increase expressiveness in conditions. For example, a contract might use these operators: 
     11.code 
     12        def foo(items as IList<of Item>) 
     13                require all for item in items get item.name.trim.length > 0 
    914 
    1015* Added generic methods. 
  • cobra/trunk/Source/CobraLang.cs

    r1526 r1564  
    521521        } 
    522522 
     523        static public bool All<T>(IEnumerable<T> items) { 
     524                foreach (T item in items) 
     525                        if (!IsTrue(item)) 
     526                                return false; 
     527                return true; 
     528        } 
     529 
     530        static public bool All(IEnumerable items) { 
     531                foreach (object item in items) 
     532                        if (!IsTrue(item)) 
     533                                return false; 
     534                return true; 
     535        } 
     536 
     537        static public bool Any<T>(IEnumerable<T> items) { 
     538                foreach (T item in items) 
     539                        if (IsTrue(item)) 
     540                                return true; 
     541                return false; 
     542        } 
     543 
     544        static public bool Any(IEnumerable items) { 
     545                foreach (object item in items) 
     546                        if (IsTrue(item)) 
     547                                return true; 
     548                return false; 
     549        } 
     550  
    523551        static public bool In(string a, string b) { 
    524552                return b.Contains(a); 
  • cobra/trunk/Source/CobraParser.cobra

    r1562 r1564  
    23802380                        'TILDE': _binaryOpPrec['PLUS']+1, 
    23812381                        'NOT':   _binaryOpPrec['AND']+1, 
     2382                        'ALL':   _binaryOpPrec['AND']+1,  # have to admit I'm just guessing at the precendence level for 'any' and 'all'. experience will tell. TODO: fix or not, then retire this comment (2008-07-31) 
     2383                        'ANY':   _binaryOpPrec['AND']+1, 
    23822384                        'REF':   _binaryOpPrec['STARSTAR']+1, 
    23832385                        'OLD':   _binaryOpPrec['STARSTAR']+1, 
     
    24792481                        token = .grab 
    24802482                        prec = _unaryOpPrec[peek] 
     2483                        unaryExpr = .expression(prec) 
    24812484                        branch token.which 
    2482                                 on 'OLD' 
    2483                                         return OldExpr(token, .expression(prec)) 
    2484                                 on 'REF' 
    2485                                         refTo = .expression(prec) 
    2486                                         return RefExpr(token, refTo) 
    2487                                 else 
    2488                                         return UnaryOpExpr(token, peek, .expression(prec)) 
     2485                                on 'ALL', return AllExpr(token, unaryExpr) 
     2486                                on 'ANY', return AnyExpr(token, unaryExpr) 
     2487                                on 'OLD', return OldExpr(token, unaryExpr) 
     2488                                on 'REF', return RefExpr(token, unaryExpr) 
     2489                                else, return UnaryOpExpr(token, peek, unaryExpr) 
    24892490                # TODO: make a branch statement 
    24902491                else if peek=='LPAREN' 
  • cobra/trunk/Source/Expr.cobra

    r1562 r1564  
    23782378 
    23792379 
     2380class AllOrAnyExpr 
     2381        is abstract 
     2382        inherits Expr 
     2383        """ 
     2384        The base class for AllExpr and AnyExpr which have much in common. 
     2385         
     2386        They are unary prefix operators taking something enumerable and returning a bool. 
     2387        """ 
     2388 
     2389        var _expr as Expr 
     2390 
     2391        def init(token as IToken, expr as Expr) 
     2392                base.init(token) 
     2393                _expr = expr 
     2394 
     2395        get opName as String is abstract 
     2396 
     2397        get expr from var 
     2398 
     2399        get hasError as bool 
     2400                if base.hasError, return true 
     2401                if .expr.hasError, return true 
     2402                return false 
     2403 
     2404        get willChangeVar as bool is override 
     2405                if base.willChangeVar, return true 
     2406                if .expr.willChangeVar, return true 
     2407                return false 
     2408 
     2409        def addSubFields is override 
     2410                base.addSubFields 
     2411                .addField('expr', _expr) 
     2412 
     2413        def toCobraSource as String is override 
     2414                return '[.opName] [.expr.toCobraSource]' 
     2415 
     2416        def _bindImp 
     2417                base._bindImp 
     2418                _type = .compiler.boolType 
     2419                _expr.bindImp 
     2420                enumerable = .compiler.libraryBox('System.Collections.IEnumerable') 
     2421                if _expr.type.isDescendantOf(enumerable) 
     2422                        pass 
     2423                else if _expr.type.isDynamic 
     2424                        _expr.contextType = enumerable 
     2425                else 
     2426                        .throwError('Expecting an enumerable expression after "[.opName]", but got an expression of type "[.expr.type.name]".') 
     2427 
     2428        def writeSharpDef(sw as SharpWriter, parens as bool) is override 
     2429                sw.write('CobraImp.[Utils.capped(.opName)](') 
     2430                .expr.writeSharpDefInContext(sw) 
     2431                sw.write(')') 
     2432 
     2433        def writeSharpBreakdownItems(sw as SharpWriter) 
     2434                base.writeSharpBreakdownItems(sw) 
     2435                sw.write(', +1') 
     2436                .expr.writeSharpBreakdownItems(sw) 
     2437                sw.write(', -1') 
     2438 
     2439 
     2440class AllExpr 
     2441        inherits AllOrAnyExpr 
     2442        """ 
     2443        all <enumerable> --> true if all elements are true 
     2444        """ 
     2445         
     2446        def init(token as IToken, expr as Expr) 
     2447                base.init(token, expr) 
     2448 
     2449        get opName as String is override 
     2450                return 'all' 
     2451         
     2452 
     2453class AnyExpr 
     2454        inherits AllOrAnyExpr 
     2455        """ 
     2456        any <enumerable> --> true if any element is true 
     2457        """ 
     2458         
     2459        def init(token as IToken, expr as Expr) 
     2460                base.init(token, expr) 
     2461 
     2462        get opName as String is override 
     2463                return 'any' 
     2464 
     2465 
    23802466class UnaryOpExpr 
    23812467        inherits Expr 
  • cobra/trunk/Tests/500-dynamic/104-dynamic-ops.cobra

    r1474 r1564  
    175175                xq = 'aoeu' 
    176176                assert not not xq 
     177 
     178                t as dynamic = [1, 2, 3] 
     179                assert all t 
     180                assert any t 
     181                t.add(0) 
     182                assert not all t 
     183                assert any t 
     184                t = [0] 
     185                assert not all t 
     186                assert not any t 
     187                t.clear 
     188                assert all t 
     189                assert not any t