Wiki

Ticket #315: multiReturn.patch

File multiReturn.patch, 25.5 KB (added by hopscc, 12 years ago)
  • Source/Members.cobra

     
    836836            return _returnType to ! 
    837837 
    838838    get statements from _stmts 
     839     
     840    #following 3 for use while parsing for methods with multiple return values 
     841    pro hasMultipleReturnValues from var as bool 
    839842 
     843    get numReturnValues as int 
     844        require _returnTypeNode inherits GenericTypeIdentifier 
     845        rtn = _returnTypeNode to GenericTypeIdentifier 
     846        return rtn.numArgs 
     847         
     848    get returnedTypes as List<of ITypeProxy> 
     849        """List of return types for method with multiple return values""" 
     850        require _returnTypeNode inherits GenericTypeIdentifier 
     851        rtn = _returnTypeNode to GenericTypeIdentifier 
     852        return rtn.typeNodes to ! 
     853     
    840854    def findLocal(name as String) as AbstractLocalVar? 
    841855        # TODO: should this use a dictionary lookup? 
    842856        for local in _locals, if local.name == name, return local 
  • Source/CobraParser.cobra

     
    13721372            .throwError('Method names cannot be the same as their enclosing [curBox.englishName]. Use `cue init` for creating an initializer/constructor or choose another name.')  # TODO list the enclosing types location 
    13731373 
    13741374        params = _methodParams(opener) 
    1375         returnType = _methodReturnType 
     1375        isMultiReturn as bool 
     1376        returnType = _methodReturnType(out isMultiReturn) 
    13761377 
    13771378        isNames = List<of String>(_isNamesStack) 
    13781379        attribs = AttributeList() 
     
    14291430            method = Initializer(token, opener, .curBox, params, isNames, attribs, docString) to AbstractMethod 
    14301431        else 
    14311432            method = Method(token, opener, .curBox, name, .makeList<of IType>(genericParams), params, returnType, implementsType, isNames, attribs, docString) 
     1433        method.hasMultipleReturnValues = isMultiReturn   
    14321434        if nothingMore 
    14331435            if method.bodyExclusion is nil, .throwError('Missing method body for "[name]".') 
    14341436        else 
     
    14481450            genericParams = List<of GenericParam>() 
    14491451        return genericParams     
    14501452         
    1451     def _methodReturnType as ITypeProxy 
     1453    def _methodReturnType(isMultiReturn as out bool) as ITypeProxy 
    14521454        """ Returns declared method return type or void type if none declared. Helper for .declareMethod. """ 
     1455        isMultiReturn = false 
    14531456        if .optional('AS') 
    1454             returnType = .typeId to ITypeProxy 
     1457            retTypes = List<of ITypeProxy>() 
     1458            _commaSepTypes(retTypes) 
     1459            #returnType = .typeId to ITypeProxy 
     1460            if retTypes.count == 1 
     1461                returnType = retTypes[0] 
     1462            else 
     1463                token = (retTypes[0] to AbstractTypeIdentifier).token                
     1464                returnType = _mkMultiReturnType(token, retTypes) 
     1465                isMultiReturn = true 
    14551466        else 
    14561467            returnType = _typeProvider.voidType 
    14571468        return returnType 
    1458  
     1469         
     1470    def _mkMultiReturnType(token as IToken, types as List<of ITypeProxy>) as AbstractTypeIdentifier 
     1471        """ 
     1472        Make the (generic) container type for the ordered list of multiple return types. 
     1473            'as int, String' becomes 'as Bag<int, String>' 
     1474        """   
     1475        if types.count > 4 
     1476            .throwError('Cannot have more than 4 return values in a method returning multiple values.') 
     1477        rootName = 'Pair' # 'Bag' 
     1478        fullName = rootName + '<of ' + ', '.repeat(types.count-1) + '>' 
     1479        openGenericToken = token.copy('OPEN_GENERIC', rootName+'<of ', rootName) 
     1480        genericBag = GenericTypeIdentifier(openGenericToken, rootName, fullName, types) 
     1481        return genericBag 
     1482             
    14591483    def _methodParams(opener as IToken) as List<of Param> 
    14601484        """ Returns a list of declared parameters, possibly empty if there were none declared. Helper for .declareMethod. """ 
    14611485        unnecessary = false 
     
    24512475 
    24522476    def returnStmt as Stmt 
    24532477        token = .expect('RETURN') 
    2454         expr = if(.peek.which == 'EOL', nil, .expression) 
     2478        #expr = if(.peek.which == 'EOL', nil, .expression) 
     2479        if .peek.which == 'EOL' 
     2480            expr = nil 
     2481        else if not _curCodePart.hasMultipleReturnValues 
     2482            expr = .expression 
     2483        else     
     2484            exprs = .commaSepExprs('EOL.') 
     2485            assert .last.which=='EOL' 
     2486            .ungrab  # need EOL 
     2487            postCallToken = exprs[0].token.copy('LPAREN', '(', '(') 
     2488            expr = _mkMultiReturn(postCallToken,  exprs) 
    24552489        return ReturnStmt(token, expr) 
     2490         
     2491    def _mkMultiReturn(postCallToken as IToken, exprs as List<of Expr>) as PostCallExpr 
     2492        """ 
     2493        Make the container for the expressions returned for a return of multiple values. 
     2494        Something like      return i, 'val'  
     2495        gets turned into    return Bag<of int,String>(i, 'val') 
     2496        """  
     2497        require _curCodePart.hasMultipleReturnValues 
     2498        if exprs.count > 4 
     2499            .throwError('Cannot have more than 4 return values in a multiple value return statement.') 
     2500        if exprs.count <> _curCodePart.numReturnValues 
     2501            .throwError('Method declared to return [_curCodePart.numReturnValues] return values but [exprs.count] given.') 
    24562502 
     2503        returnTypes = _curCodePart.returnedTypes             
     2504        rootName = 'Pair' # -> 'Bag' 
     2505        fullName = rootName + '<of ' + ', '.repeat(exprs.count-1) + '>' 
     2506        openGenericToken = postCallToken.copy('OPEN_GENERIC', rootName+'<of ', rootName) 
     2507        genBag = GenericTypeIdentifier(openGenericToken, rootName, fullName, returnTypes) 
     2508        return PostCallExpr(postCallToken, TypeExpr(genBag), exprs)      
     2509 
    24572510    def _isIndentedContract as bool 
    24582511        require .peek.which.isOneOf('REQUIRE.ENSURE.OR.AND.') 
    24592512        offset = 0 
  • Source/Cobra.Core/files.text

     
    1717NumericTypes.cobra 
    1818ObjectCatalog.cobra 
    1919Pair.cobra 
     20Bag.cobra 
    2021Set.cobra 
    2122SourceSite.cobra 
    2223StringMaker.cobra 
  • Source/Cobra.Core/Bag.cobra

     
     1"""  
     2    Bag - multivalue collection, 2, 3 and 4 items, each item fully and separately typed 
     3"""  
     4     
     5namespace Cobra.Core 
     6 
     7    class Bag<of TA, TB> inherits Pair<of TA, TB> 
     8        implements System.Collections.IEnumerable, IComparable<of Bag<of TA, TB>> 
     9        """ Bag<of,> 2 item bag - Thin wrapper around Pair<T1, T2> """ 
     10         
     11        cue init(a as TA, b as TB) 
     12            base.init(a, b) 
     13         
     14        def toString as String is override 
     15            sa = CobraCore.toTechString(.a) 
     16            sb = CobraCore.toTechString(.b) 
     17            return 'Bag([sa], [sb])' 
     18 
     19        def equals(obj as Object?) as bool is override 
     20            test 
     21                assert Pair<of String, String>('a', 'b') == Pair<of String, String>('a', 'b') 
     22                assert Pair<of String, String>('a', 'b') <> Pair<of String, String>('a', 'c') 
     23            body 
     24                if obj is nil, return false 
     25                if not (obj to? Bag<of TA, TB>), return false # not this Type 
     26                if obj is this, return true 
     27                if obj inherits Pair<of TA, TB>  
     28                    return obj.a == .a and obj.b == .b 
     29                return false 
     30                 
     31        def equals(b as Bag<of TA, TB>) as bool 
     32            # suppress through calls fm superclass so equivalent subset (type and values same) not map equal 
     33            # superclasses must do own independent equality checking not using base.equals 
     34            if b.getType <> Bag<of TA, TB>, return false 
     35            return base.equals(b to Pair<of TA, TB>) 
     36         
     37        def compareTo(b as Bag<of TA, TB>) as int 
     38            test 
     39                assert Bag<of String, int>('a', 3) < Bag<of String, int>('b', 4) 
     40                assert Bag<of String, int>('a', 3) < Bag<of String, int>('a', 4) 
     41                assert Bag<of String, int>('a', 3) <= Bag<of String, int>('a', 3) 
     42                assert Bag<of int, int>(2, 3) > Bag<of int, int>(2, 2) 
     43                assert Bag<of int, int>(2, 3) >= Bag<of int, int>(2, 3) 
     44                assert Bag<of String, int>('a', 3).compareTo(Bag<of String, int, char>('a', 3, c'b')) == 0 
     45# on-hold. to-do 
     46#               assert Bag<of String?, String?, String?>(nil, 'a', 'a') < Bag<of String?, String?, String?>(nil, 'b', 'a') 
     47#               assert Bag<of String?, String?, String?>(nil, 'a', 'a') < Bag<of String?, String?, String?>(nil, 'a', 'b') 
     48#               assert Bag<of int?, int?, int?>(nil, nil, nil) < Bag<of int?, int?, int?>(1, 1, 1) 
     49            body 
     50                return base.compareTo(b) 
     51             
     52             
     53                 
     54    #            
     55    # 3-Bag built on 2-Bag 
     56    #        
     57    class Bag<of TA, TB, TC> inherits Bag<of TA, TB> 
     58        implements System.Collections.IEnumerable, IComparable<of Bag<of TA, TB, TC>> 
     59        """ Bag<of,,> - 3 item Bag - values separately typed""" 
     60         
     61        test 
     62            b = Bag<of int, int, int>(1, 2, 3) 
     63            assert b.a == 1 and b.b == 2 and b.c == 3 
     64            assert b[0] == 1 and b[1] == 2 and b[2] == 3 
     65            assert b.toString == 'Bag(1, 2, 3)' 
     66            expect IndexOutOfRangeException, assert b[3] == 3 
     67             
     68            b1 = Bag<of int, String, int>(1, 'a', 1) 
     69            assert b1.a == 1 and b1.b == 'a' and b1.c == 1 
     70            assert b1[0] == 1 and b1[1] == 'a' and b1[2] == 1 
     71            assert b1.toString == "Bag(1, 'a', 1)" 
     72            expect IndexOutOfRangeException, assert b1[3] == 3 
     73             
     74         
     75        cue init(a as TA, b as TB, c as TC ) 
     76            base.init(a, b) 
     77            _c = c 
     78             
     79        get c from var as TC 
     80 
     81        get [i as int] as dynamic? is new 
     82            if i == 0, return .a 
     83            if i == 1, return .b 
     84            if i == 2, return _c 
     85            throw IndexOutOfRangeException('Index [i] is out of range for a 3 bag (0-2).') 
     86         
     87        def toString as String is override 
     88            sa = CobraCore.toTechString(.a) 
     89            sb = CobraCore.toTechString(.b) 
     90            sc = CobraCore.toTechString(.c) 
     91            return 'Bag([sa], [sb], [sc])' 
     92 
     93        def equals(other as Bag<of TA, TB, TC>) as bool 
     94            test 
     95                assert Bag<of String, int, char>('a', 99, c'b').equals(Bag<of String,int, char>('a', 99, c'b')) 
     96                assert not Bag<of String, int, char>('a', 99, c'b').equals(Bag<of String, int, char>('a', 98, c'b')) 
     97                assert not Bag<of String, int, char>('a', 99, c'b').equals(Bag<of String, int, char>('a', 99, c'c')) 
     98            body 
     99                if other.getType <> Bag<of TA, TB, TC>, return false # disallow superclasses 
     100                return other.a ==.a and other.b ==.b and other.c ==.c 
     101 
     102        def equals(obj as Object?) as bool is override 
     103            test 
     104                assert Bag<of String, String, int>('a', 'b', 1) == Bag<of String, String, int>('a', 'b', 1) 
     105                assert Bag<of String, String, int>('a', 'b', 1) <> Bag<of String, String, int>('a', 'c', 1) 
     106                assert Bag<of String, String, int>('a', 'b', 1) <> Bag<of String, String, int>('a', 'b', 2) 
     107                assert Bag<of String, String>('a', 'c')        <> Bag<of String, String, int>('a', 'b', 1)  
     108            body 
     109                if obj inherits Bag<of TA, TB, TC> 
     110                    return .equals(obj) 
     111                return false 
     112 
     113        # block equals against base class instances 
     114        def equals(p as Pair<of TA, TB>) as bool is override 
     115            test 
     116                assert Bag<of String, String, int>('a', 'b', 1) <> Pair<of String, String>('a', 'b') 
     117                assert not Bag<of String, String, int>('a', 'b', 1) == Pair<of String, String>('a', 'b') 
     118                # this fail - probably testing into Pair rather than here 
     119                #assert Pair<of String, String>('a', 'b')        <> Bag<of String, String, int>('a', 'b', 1)  
     120            body 
     121                return false 
     122             
     123        # block equals against base class instances 
     124        def equals(p as Bag<of TA, TB>) as bool is override 
     125            test 
     126                assert Bag<of String, String, int>('a', 'b', 1) <> Bag<of String, String>('a', 'b') 
     127                assert not Bag<of String, String, int>('a', 'b', 1) == Bag<of String, String>('a', 'b') 
     128                assert Bag<of String, String>('a', 'b')        <> Bag<of String, String, int>('a', 'b', 1)  
     129            body 
     130                return false 
     131                 
     132        def compareTo(b as Bag<of TA, TB, TC>) as int 
     133            test 
     134                assert Bag<of String, int, char>('a', 3, c'b') < Bag<of String, int, char>('b', 4, c'b') 
     135                assert Bag<of String, int, char>('a', 3, c'b') < Bag<of String, int, char>('a', 4, c'b') 
     136                assert Bag<of String, int, char>('a', 3, c'b') < Bag<of String, int, char>('a', 3, c'c') 
     137                assert Bag<of int, int, int>(2, 3, 4) > Bag<of int, int, int>(2, 2, 4) 
     138                assert Bag<of int, int, int>(2, 3, 4) > Bag<of int, int, int>(2, 3, 3) 
     139                assert Bag<of String, int, char>('a', 3, c'b').compareTo(Bag<of String, int, char>('a', 3, c'b')) == 0 
     140# on-hold. to-do 
     141#               assert Bag<of String?, String?, String?>(nil, 'a', 'a') < Bag<of String?, String?, String?>(nil, 'b', 'a') 
     142#               assert Bag<of String?, String?, String?>(nil, 'a', 'a') < Bag<of String?, String?, String?>(nil, 'a', 'b') 
     143#               assert Bag<of int?, int?, int?>(nil, nil, nil) < Bag<of int?, int?, int?>(1, 1, 1) 
     144            body 
     145                diff = base.compareTo(b) 
     146                if diff == 0, diff = _compare(.c, b.c) 
     147                return diff 
     148 
     149        def getHashCode as int is override 
     150            test 
     151                assert Bag<of int, String, int>(1, 'one', 1).getHashCode == Bag<of int, String, int>(1, 'one', 1).getHashCode  
     152                assert Bag<of int, int, int>(2, 2, 2).getHashCode == Bag<of int, int, int>(2, 2, 2).getHashCode 
     153                assert Bag<of int, String, int>(1, 'one', 1).getHashCode <> Bag<of int, int, int>(2, 2, 2).getHashCode 
     154                assert Bag<of int, int, int>(2, 2, 2).getHashCode <> Bag<of int, int, int>(2, 2, 1).getHashCode 
     155                d = { 
     156                    Bag<of int, String, int>(1, 'one', 1): 'one', 
     157                    Bag<of int, int, int>(2, 2, 2): 'two', 
     158# to-do                 Bag<of dynamic, dynamic, dynamic>(nil, nil, nil): 'nil', 
     159                } 
     160 
     161                assert d[Bag<of int, String, int>(1, 'one', 1)] == 'one' 
     162                assert d[Bag<of int, int, int>(2, 2, 2)] == 'two' 
     163# to-do             assert d[Bag<of dynamic, dynamic, dynamic>(nil, nil, nil)] == 'nil' 
     164            body 
     165                return HashCodeUtils.combine(base.getHashCode, if(.c is nil, 0, .c.getHashCode)) 
     166 
     167        def getEnumerator as System.Collections.IEnumerator is override 
     168            test 
     169                assert (for s in Bag<of String, String, String>('a', 'b', 'c') get s) == ['a', 'b', 'c'] 
     170                assert (for s in Bag<of String, String, int>('a', 'b', 99) get s) == ['a', 'b', 99] 
     171            body 
     172                yield .a 
     173                yield .b 
     174                yield .c 
     175 
     176    #            
     177    # 4-Bag built on 3-bag 
     178    #        
     179    class Bag<of TA, TB, TC, TD> inherits Bag<of TA, TB, TC> 
     180        implements System.Collections.IEnumerable, IComparable<of Bag<of TA, TB, TC, TD>> 
     181        """ Bag<of,,,> - 4 item Bag - values separately typed""" 
     182         
     183        test 
     184            b = Bag<of int, int, int, int>(1, 2, 3, 4) 
     185            assert b.a == 1 and b.b == 2 and b.c == 3 and b.d ==4 
     186            assert b[0] == 1 and b[1] == 2 and b[2] == 3 and b[3] ==4 
     187            assert b.toString == 'Bag(1, 2, 3, 4)' 
     188            expect IndexOutOfRangeException, assert b[4] == 3 
     189             
     190            b1 = Bag<of int, String, int, String>(1, 'a', 1, 'a') 
     191            assert b1.a == 1 and b1.b == 'a' and b1.c == 1 and b1.d == 'a' 
     192            assert b1[0] == 1 and b1[1] == 'a' and b1[2] == 1 and b1[3] == 'a' 
     193            assert b1.toString == "Bag(1, 'a', 1, 'a')" 
     194            expect IndexOutOfRangeException, assert b1[4] == 3 
     195             
     196         
     197        cue init(a as TA, b as TB, c as TC, d as TD) 
     198            base.init(a, b, c) 
     199            _d = d 
     200             
     201        get d from var as TD 
     202 
     203        get [i as int] as dynamic? is new 
     204            if i == 0, return .a 
     205            if i == 1, return .b 
     206            if i == 2, return .c 
     207            if i == 3, return _d 
     208            throw IndexOutOfRangeException('Index [i] is out of range for a 4 bag (0-3).') 
     209         
     210        def toString as String is override 
     211            sa = CobraCore.toTechString(.a) 
     212            sb = CobraCore.toTechString(.b) 
     213            sc = CobraCore.toTechString(.c) 
     214            sd = CobraCore.toTechString(.d) 
     215            return 'Bag([sa], [sb], [sc], [sd])' 
     216 
     217        def equals(other as Bag<of TA, TB, TC, TD>) as bool 
     218            test 
     219                assert Bag<of String, int, char, int>('a', 99, c'b', 1).equals(Bag<of String,int, char, int>('a', 99, c'b', 1)) 
     220                assert not Bag<of String, int, char, int>('a', 99, c'b', 1).equals(Bag<of String, int, char, int>('a', 98, c'b', 1)) 
     221                assert not Bag<of String, int, char, int>('a', 99, c'b', 1).equals(Bag<of String, int, char, int>('a', 99, c'c', 1)) 
     222                assert not Bag<of String, int, char, int>('a', 99, c'b', 1).equals(Bag<of String, int, char, int>('a', 99, c'b', 2)) 
     223            body 
     224                if other.getType <> Bag<of TA, TB, TC, TD>, return false # disallow equality on superclasses 
     225                return other.a ==.a and other.b ==.b and other.c ==.c and other.d == .d 
     226 
     227        def equals(obj as Object?) as bool is override 
     228            test 
     229                assert Bag<of String, String, int, int>('a', 'b', 1, 1) == Bag<of String, String, int, int>('a', 'b', 1, 1) 
     230                assert Bag<of String, String, int, int>('a', 'b', 1, 1) <> Bag<of String, String, int, int>('a', 'c', 1, 1) 
     231                assert Bag<of String, String, int, int>('a', 'b', 1, 1) <> Bag<of String, String, int, int>('a', 'b', 2, 1) 
     232                assert Bag<of String, String, int, int>('a', 'b', 1, 1) <> Bag<of String, String, int, int>('a', 'b', 1, 2) 
     233                assert Bag<of String, String, int>('a', 'b', 1)  <> Bag<of String, String, int, int>('a', 'b', 1, 1)  
     234            body 
     235                if obj inherits Bag<of TA, TB, TC, TD> 
     236                    return .equals(obj) 
     237                return false 
     238 
     239        # block equals against base class instances 
     240        def equals(p as Bag<of TA, TB, TC>) as bool is override 
     241            test 
     242                assert Bag<of String, String, int, int>('a', 'b', 1, 1) <> Bag<of String, String, int>('a', 'b', 1) 
     243                assert not Bag<of String, String, int, int>('a', 'b', 1, 1) == Bag<of String, String, int>('a', 'b', 1) 
     244                assert Bag<of String, String, int>('a', 'b', 1)  <> Bag<of String, String, int, int>('a', 'b', 1, 1)  
     245            body 
     246                return false 
     247                 
     248        def compareTo(b as Bag<of TA, TB, TC, TD>) as int 
     249            test 
     250                assert Bag<of String, int, char, int>('a', 3, c'b', 1) < Bag<of String, int, char, int>('b', 4, c'b', 1) 
     251                assert Bag<of String, int, char, int>('a', 3, c'b', 1) < Bag<of String, int, char, int>('a', 3, c'c', 1) 
     252                assert Bag<of String, int, char, int>('a', 3, c'b', 1) < Bag<of String, int, char, int>('a', 3, c'b', 2) 
     253                assert Bag<of int, int, int, int>(2, 3, 4, 5) > Bag<of int, int, int, int>(2, 2, 4, 5) 
     254                assert Bag<of int, int, int, int>(2, 3, 4, 5) > Bag<of int, int, int, int>(2, 3, 3, 5) 
     255                assert Bag<of int, int, int, int>(2, 3, 4, 5) > Bag<of int, int, int, int>(2, 3, 4, 4) 
     256                assert Bag<of String, int, char, int>('a', 3, c'b', 1).compareTo(Bag<of String, int, char, int>('a', 3, c'b', 1)) == 0 
     257                assert Bag<of int, int, int, int>(2, 3, 4, 5).compareTo(Bag<of int, int, int, int>(2, 3, 4, 4)) > 0 
     258                assert Bag<of int, int, int, int>(2, 3, 4, 5).compareTo(Bag<of int, int, int, int>(2, 3, 4, 6)) <0 
     259# on-hold. to-do 
     260#               assert Bag<of String?, String?, String?>(nil, 'a', 'a') < Bag<of String?, String?, String?>(nil, 'b', 'a') 
     261#               assert Bag<of String?, String?, String?>(nil, 'a', 'a') < Bag<of String?, String?, String?>(nil, 'a', 'b') 
     262#               assert Bag<of int?, int?, int?>(nil, nil, nil) < Bag<of int?, int?, int?>(1, 1, 1) 
     263            body 
     264                diff = base.compareTo(b) 
     265                if diff == 0, diff = _compare(.d, b.d) 
     266                return diff 
     267 
     268        def getHashCode as int is override 
     269            test 
     270                assert Bag<of int, String, int, int>(1, 'one', 1, 1).getHashCode == Bag<of int, String, int, int>(1, 'one', 1, 1).getHashCode  
     271                assert Bag<of int, int, int, int>(2, 2, 2, 2).getHashCode == Bag<of int, int, int, int>(2, 2, 2, 2).getHashCode 
     272                assert Bag<of int, String, int, int>(1, 'one', 1, 1).getHashCode <> Bag<of int, int, int, int>(2, 2, 2, 2).getHashCode 
     273                assert Bag<of int, int, int, int>(2, 2, 2, 2).getHashCode <> Bag<of int, int, int, int>(2, 2, 2, 1).getHashCode 
     274                d = { 
     275                    Bag<of int, String, int, int>(1, 'one', 1, 1): 'one', 
     276                    Bag<of int, int, int, int>(2, 2, 2, 2): 'two', 
     277# to-do                 Bag<of dynamic, dynamic, dynamic>(nil, nil, nil): 'nil', 
     278                } 
     279 
     280                assert d[Bag<of int, String, int, int>(1, 'one', 1, 1)] == 'one' 
     281                assert d[Bag<of int, int, int, int>(2, 2, 2, 2)] == 'two' 
     282# to-do             assert d[Bag<of dynamic, dynamic, dynamic>(nil, nil, nil)] == 'nil' 
     283            body 
     284                return HashCodeUtils.combine(base.getHashCode, if(.d is nil, 0, .d.getHashCode)) 
     285 
     286        def getEnumerator as System.Collections.IEnumerator is override 
     287            test 
     288                assert (for s in Bag<of String, String, String, String>('a', 'b', 'c', 'd') get s) == ['a', 'b', 'c', 'd'] 
     289                assert (for s in Bag<of String, String, int, int>('a', 'b', 99, 1) get s) == ['a', 'b', 99, 1] 
     290            body 
     291                yield .a 
     292                yield .b 
     293                yield .c 
     294                yield .d 
     295                 
     296                 
     297class BagExerciser 
     298    def main is shared 
     299        print 'Test' 
     300        b = Bag<of int, String, int>(1, 'xx', 1) 
     301        assert b.a == 1 and b.b=='xx' and b.c ==1 
     302        assert b.a.typeOf == Int32 
     303        assert b.b.typeOf == String 
     304         
     305        d = Bag<of int, String, int, char>(1, 'xx', 1, c'a') 
     306        assert d.a == 1 and d.b=='xx' and d.c ==1 and d.d == c'a' 
     307        assert d.a.typeOf == Int32 
     308        assert d.b.typeOf == String 
     309        assert d.d.typeOf == Char 
     310     
     311        ty = [Int32, String, Int32, Char] 
     312        i=0 
     313        for o in d 
     314            assert o == d[i] 
     315            assert o.getType == ty[i] 
     316            i += 1 
     317 
     318        #print b.toString 
     319        #print d.toString    
  • Tests/200-misc/450-multi-return/550-mismatch.cobra

     
     1class MultiRet 
     2    def main is shared 
     3        m = MultiRet() 
     4        a, b = m.call 
     5        assert a == 'hi' 
     6        assert err == 1 
     7     
     8         
     9    def call as int, int, int, int, int # .error. more than 4 
     10        err=1 
     11        s = 'hi' 
     12        return err, 1, 2, 3, 5  
  • Tests/200-misc/450-multi-return/560-mismatch.cobra

     
     1class MultiRet 
     2    def main is shared 
     3        m = MultiRet() 
     4        a, b = m.call 
     5        assert a == 'hi' 
     6        assert err == 1 
     7     
     8         
     9    def call as int, int 
     10        err=1 
     11        s = 'hi' 
     12        return err, 1, 2, 3, 5  # .error. more than 4 
  • Tests/200-misc/450-multi-return/100-multi-return-orig.cobra

     
     1# can do typed multi return without syntax support using explicit Pair 
     2class MultiRet 
     3    def main is shared 
     4        m = MultiRet() 
     5        a, err = m.call 
     6        assert a == 'hi' 
     7        assert err == 1 
     8     
     9    # works now (only for 2 vals) 
     10    def call as Pair<of String, int> 
     11        err=1 
     12        s = 'hi' 
     13        return Pair<of String, int>(s, err) 
     14         
  • Tests/200-misc/450-multi-return/200-multi-return.cobra

     
     1# Multireturn syntax supported 
     2class MultiRet 
     3    def main is shared 
     4        m = MultiRet() 
     5        a, err = m.call 
     6        assert a == 'hi' 
     7        assert err == 1 
     8     
     9    def call as String, int 
     10        err=1 
     11        s = 'hi' 
     12        return s, err 
     13         
  • Tests/200-misc/450-multi-return/210-multi-return.cobra

     
     1# Multireturn syntax supported 
     2class MultiRet 
     3    def main is shared 
     4        m = MultiRet() 
     5        a, err = m.call 
     6        assert a == 'hi' 
     7        assert err == 'No Error' 
     8     
     9    def call as String, String 
     10        err='No Error' 
     11        s = 'hi' 
     12        return s, err 
     13         
  • Tests/200-misc/450-multi-return/500-mismatch.cobra

     
     1class MultiRet 
     2    def main is shared 
     3        m = MultiRet() 
     4        a, err = m.call 
     5        assert a == 'hi' 
     6        assert err == 1 
     7     
     8         
     9    def call as String, int 
     10        err=1 
     11        s = 'hi' 
     12        return Pair<of String, int>(s, err) # .error. declared to return 2 
     13         
  • Tests/200-misc/450-multi-return/220-multi-return.cobra

     
     1class MultiRet 
     2    def main is shared 
     3        m = MultiRet() 
     4        err, a = m.call 
     5        assert err == 'No Error' 
     6        assert a.typeOf == X 
     7     
     8    def call as String, X 
     9        err='No Error' 
     10        return err, X() 
     11         
     12         
     13class X 
     14    pass 
  • Tests/200-misc/450-multi-return/510-mismatch.cobra

     
     1class MultiRet 
     2    def main is shared 
     3        m = MultiRet() 
     4        a, err = m.go 
     5        assert a == 'hi' 
     6        assert err == 1 
     7     
     8         
     9    def go as String, int 
     10        err=1 
     11        s = 'hi' 
     12        return  99 # .error. declared to return 2 
     13         
  • Tests/200-misc/450-multi-return/230-multi-return.cobra

     
     1class MultiRet 
     2    def main is shared 
     3        m = MultiRet() 
     4        err, a = m.call 
     5        assert err == 'No Error' 
     6        assert a.typeOf == X 
     7     
     8    def call as String, X 
     9        err='No Error' 
     10        x = X() 
     11        return err, x 
     12         
     13         
     14class X 
     15    pass 
  • Tests/200-misc/450-multi-return/520-mismatch.cobra

     
     1class MultiRet 
     2    def main is shared 
     3        m = MultiRet() 
     4        a, err = m.go 
     5        assert a == 'hi' 
     6        assert err == 1 
     7     
     8         
     9    def go as int 
     10        err=1 
     11        s = 'hi' 
     12        return  s, err1 # .error. Expecting EOL 
     13