Wiki

Ticket #273: tweaks.patch

File tweaks.patch, 19.7 KB (added by hopscc, 14 years ago)
  • Source/Cobra.Lang/Extensions.cobra

     
    66    extend System.Object 
    77 
    88        def typeOf as System.Type 
    9             """ Using .typeOf is portable between platforms in contrast to CLR .getType and JVM .getClass. """ 
     9            """ 
     10            Return the Type of the object this is called on.  
     11            Using .typeOf is portable between platforms in contrast to CLR .getType and JVM .getClass. 
     12            """ 
    1013            return .getType 
    1114 
    1215        def toTechString as String 
     16            """ 
     17            Generate a 'technical' string representation of the object suitable for inspection and debugging. 
     18            Used for AssertExceptions (and subclasses such as RequireException) and the trace statement. 
     19            It provides more information about collections and enumerations and recovers from exceptions 
     20                when making strings so that debugging can proceed. 
     21            Intended to be similar to Python's repr() behavior. 
     22            """ 
    1323            return CobraImp._techStringMaker.makeString(this) 
    1424 
    1525        def toPrintString as String 
     26            """ 
     27            Generate a string representation of the object suitable for printing. 
     28            Strings are only quoted if they are inside collections such as a list or dictionary. 
     29                This is similar to Python's str() behavior which has worked well in practice. 
     30            """      
    1631            return CobraImp._printStringMaker.makeString(this) 
    1732 
    1833 
     
    3853                return this[:1].toUpper + this[1:] 
    3954 
    4055        def count(c as char) as int 
     56            """Return a count of the number of occurrences of the char in this string.""" 
    4157            test 
    4258                assert ''.count(c'x')==0 
    4359                assert 'x'.count(c'x')==1 
     
    5066                return count 
    5167 
    5268        def isCapitalized as bool 
     69            """Return a bool indicating if this string is nonzero length and starts with an uppercase letter.""" 
    5370            test 
    5471                assert 'Aoeu'.isCapitalized 
    5572                assert 'Zaoeu'.isCapitalized 
     
    6077                return .length and this[0].isUpper 
    6178 
    6279        def md5HashInHex as String 
     80            """Return a string of Hex characters of the md5 hash of this string.""" 
    6381            ensure 
    6482                result.length == 32 
    6583            test 
     
    8199            return .split(separator, count, StringSplitOptions.None) 
    82100 
    83101        def split(separator as String, options as StringSplitOptions) as String[] 
    84             return .split(separator, 2_147_483_647, StringSplitOptions.None)  # CC: int.max 
     102            return .split(separator, 2_147_483_647, options)  # CC: int.max 
    85103 
    86104        def split(separator as String, count as int, options as StringSplitOptions) as String[] 
     105            """ 
     106            Return an array of strings being the split of this string on the separator string given, 
     107            up to a maximum of count items conforming to the given StringSplitOptions. 
     108            """ 
    87109            require 
    88110                count >= 0 
    89111            test 
     
    103125                return .split(@[separator], count, options) to ! 
    104126 
    105127        def split(chars as List<of char>) as List<of String> 
     128            """Split this string on any of the list of chars given returning a List of Strings.""" 
    106129            test 
    107130                s = 'a,b:c:d,e,f' 
    108131                assert s.split([c',', c':']) == ['a', 'b', 'c', 'd', 'e', 'f'] 
     
    110133                return List<of String>(.split(chars.toArray) to !) 
    111134     
    112135        def split(chars as IList<of char>) as List<of String> 
     136            """Split this string on any of the IList of chars given returning a List of Strings.""" 
    113137            charsArray = char[](chars.count) 
    114138            for i in chars.count, charsArray[i] = chars[i] 
    115139            return List<of String>(.split(charsArray)) 
     
    120144        def splitLines(keepEnds as bool) as List<of String> 
    121145            """ 
    122146            Returns the string split into lines, recognizing the various line endings (posix, dos/http, old mac) even if mixed within the same string. 
     147            If keepEnds is true the nl separators are left on the end of each line. 
    123148            """ 
    124149            test 
    125150                cases = [ 
     
    189214                return lines 
    190215 
    191216        def splitWords as List<of String> 
     217            """Split this string int (non whitespace) words returning them as a list of strings.""" 
    192218            test 
    193219                # preliminary: 
    194220                assert 'foo bar'.split == ['foo', 'bar'] 
  • Source/Cobra.Lang/ExtendIEnumerable.cobra

     
    4949    extend IEnumerable<of T> 
    5050 
    5151        def toList as List<of T> 
     52            """Turn an IEnumerable of T into a list of T.""" 
    5253            return List<of T>(this) 
    5354/# 
    5455    TODO: cannot do the following yet due to a bug in extensions and how they are chosen with respect to inheritance 
  • Source/Cobra.Lang/ExtendList.cobra

     
    5959                return newList 
    6060 
    6161        def get(flexibleIndex as int) as T 
     62            """ 
     63            Return item at flexibleIndex. if flexibleIndex <0 return item at flexibleIndex+count. 
     64            i.e offset from end of list  
     65            so .get(0) returns first item in list, .get(-1) returns last item, 
     66              .get(-2) returns second to last item, ...., get(-.count) returns first item. 
     67            Index values outside list index range cause RequireException. 
     68            """ 
    6269            require 
    6370                .count > 0 
    6471                (flexibleIndex >= 0 and flexibleIndex < .count) _ 
     
    6875                return this[flexibleIndex] 
    6976         
    7077        def get(flexibleIndex as int, default as T) as T 
     78            """ 
     79            Return item at flexibleIndex. if flexibleIndex <0 return item at flexibleIndex + this.count. 
     80            Index values outside list index range return default. 
     81            """  
    7182            ensure 
    7283                .count == 0 implies result == default 
    7384                (flexibleIndex > .count or flexibleIndex < -.count) _ 
     
    114125                yield KeyValuePair<of int, T>(index, this[index]) 
    115126 
    116127        def random as T 
     128            """Return an item at a random postion in the list""" 
    117129            require .count > 0 
    118130            return .random(CobraCore.random) 
    119131 
     
    122134            return this[r.next % .count] 
    123135 
    124136        def removeLast 
     137            """Remove the last item in the list.""" 
    125138            require .count > 0 
    126139            ensure .count == old .count - 1 
    127140            .removeAt(.count-1) 
    128141         
     142        def push(value as T)     
     143            """ Push value onto front/top of List. """ 
     144            .add(value) 
     145 
     146        def pop as T     
     147            """ Pop value off front/top of List. """ 
     148            require .count > 0 
     149            value = this[.count-1] 
     150            .removeLast 
     151            return value 
     152             
    129153        def reversed as List<of T> 
     154            """ Return a copy of this list reversed."""      
    130155            ensure 
    131156                result is not this 
    132157                result.count == .count 
     
    136161                return t 
    137162     
    138163        def sorted as List<of T> 
     164            """ Return a copy of this list sorted."""        
    139165            ensure 
    140166                result is not this 
    141167                result.count == .count 
     
    252278            else 
    253279                expect ArgumentOutOfRangeException, t.last 
    254280     
     281            # push/pop 
     282            t = [0] 
     283            t.pop 
     284            t.push(10) 
     285            assert t.count ==1 and t[0] == 10 
     286            t.push(11) 
     287            assert t.count == 2  
     288            assert t[0] == 10 and t[1] == 11 
     289            t.push(12) 
     290            assert t.count == 3  
     291            assert t[0] == 10 and t[1] == 11 and t[2] == 12 
     292            assert t.pop == 12 
     293            assert t.count == 2  and t[1] == 11 and t[0] == 10 
     294            t.push(21) 
     295            assert t.count == 3  and t[2] == 21 and t[1] == 11 and t[0] == 10 
     296            assert t.pop == 21 
     297            assert t.pop == 11 
     298            assert t.count ==1 and t[0] == 10 
     299            assert t.pop == 10 and t.count ==0 
     300            if hasContracts 
     301                expect RequireException, t.pop 
     302            else 
     303                expect ArgumentOutOfRangeException, t.pop 
     304             
    255305            # numbered 
    256306            t = [10, 20, 30] 
    257307            count = 0 
  • Source/Node.cobra

     
    44class SubnodesAttribute inherits Attribute 
    55    """ 
    66    Put this attribute on properties that represent a collection of subnodes of the declaring node class. 
    7     Node.reploceChild will use these properties when searching for node references to be replaced (which happens during node transformation). 
     7    Node.replaceChild will use these properties when searching for node references to be replaced (which happens during node transformation). 
    88    There may be other uses for this in the future. 
    99    The property value should respond to .indexOf(node) and "subnodes[index] = newNode" which are covered by List<of>. 
    1010    Since dynamic binding is used, inheriting from List<of> is not strictly required. 
  • Source/CobraParser.cobra

     
    11""" 
    22The Cobra Parser 
     3    Recursive descent parser for the Cobra Language.  
     4    Uses CobraTokeniser to obtain a stream of Cobra Lexical tokens, 
     5    then walks through these Tokens generating Nodes (subclasses of) for recognised constructs which get  
     6        assembled into a Tree of (Syntax)Nodes rooted on a Cobra Module (Node). 
    37 
    48Rules: 
    59    * Do not invoke Box.memberForName. Use Box.declForName instead. Inheritance relationships are not established during parsing. 
     
    9094    var _uppercaseLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 
    9195 
    9296    var _isNamesStack as Stack<of String>? 
     97        """Stack for recording modifier for items in modifier sections (e.g.shared)""" 
     98 
    9399    var _boxStack as Stack<of Box>? 
     100        """Stack to record the box the current level of box member decls is for.""" 
    94101 
    95102    var _globalNS as NameSpace? 
    96103    var _nameSpaceStack as Stack<of NameSpace> 
     
    179186 
    180187    def parseSource(fileName as String, source as String) as CobraModule 
    181188        """ 
    182         Parses module source code and returns resulting module. 
     189        Parses module source code and returns resulting (cobra) module. 
    183190        The fileName is recorded, but the file is not physically accessed. 
    184191        After parsing, .references will hold a list of any @ref directive references that were parsed. 
    185192        """ 
     
    199206 
    200207    def _preParseSource(fileName as String, source as String) as bool 
    201208        """ 
    202         Sets up for parsing, but does not invoke `parseTokens`. 
     209        Sets up for parsing - inits stack variables, generates token stream and handles explicit line continuation,  
     210            but does not invoke `parseTokens`. 
    203211        Used by `parseSource` and various test sections. 
    204212        Returns true if successful, false if there were one or more errors. 
    205         Upon success, you can use token methods lik .grab. 
     213        Upon success, you can use token methods like .grab. 
    206214        Does not .throwError but may .recordError. 
    207215        """ 
    208216        _fileName = fileName 
     
    337345 
    338346    def _parseTokens as CobraModule 
    339347        """ 
    340         Parses and then returns an instance of Module. 
     348        Parses and then returns an instance of (Cobra)Module. 
    341349        """ 
    342350        .zeroOrMore('EOL') 
    343351        docString = .docString 
     
    524532    var _syntaxForClassInheritanceMsg = 'The syntax for inheritance is to put "inherits BaseClass" on the following line, indented.' 
    525533 
    526534    def assemblyDecl as AssemblyDecl 
     535        """ 
     536        Parse attribute entries for an assembly attributes declaration 
     537        """ 
    527538        token = .expect('ID') 
    528539        assert token.text == 'assembly' 
    529540        .indent 
     
    674685                .throwError('Cannot nest a type underneath a [parentBox.englishName]')  # TODO: needs a test case 
    675686 
    676687        _boxStack.push(theClass) 
    677 #       .isNamesStack = Stack<of String> 
    678688        .bodiedBoxMemberDecls(theClass) 
    679689        _boxStack.pop 
    680690 
     
    751761        """ 
    752762        hasIsNames = false 
    753763        names = _isDeclNamesNoEOL(out hasIsNames) 
    754         if hasIsNames 
     764        if hasIsNames  
    755765            .endOfTypeSpecClause 
    756         # TODO: error on virtual and override 
    757         # TODO: error on virtual and shared 
    758         # TODO: error if 2 or more of 'public', 'protected', 'private', 'internal' 
    759766        return names 
    760767 
    761768    def _isDeclNamesNoEOL(hasIsNames as out bool) as List<of String> 
     
    781788                if .peek.text in .validIsNames 
    782789                    .throwError(.peek, 'Multiple access modifiers should be separated by commas such as "[what], [.peek.text]".') 
    783790                break 
    784         # TODO: error on virtual and override 
    785791        # TODO: error on virtual and shared 
    786         # TODO: error if 2 or more of 'public', 'protected', 'private', 'internal' 
     792        # error on non virtual and override 
     793        if 'nonvirtual' in names and 'override' in names 
     794            .recordError(.last, 'Cannot specify both "nonvirtual" and "override".') 
     795        # error if 2 or more of 'public', 'protected', 'private', 'internal' 
     796        protModCount=0 
     797        for p in _validProtModifiers 
     798            if p in names, protModCount += 1 
     799        if protModCount > 1 
     800            .recordError(.last, 'Can only specify one of "public", "protected", "private" or "internal".') 
    787801        return names 
    788802 
    789803    var _validIsNames as List<of String>? 
     804    var _validProtModifiers = ['public', 'protected', 'private', 'internal'] 
    790805 
    791806    get validIsNames as List<of String> 
    792807        if _validIsNames is nil 
     
    867882 
    868883        # TODO when supporting nested classes, look at the _boxStack and set a back pointer here 
    869884        _boxStack.push(theMixin) 
    870 #       .isNamesStack = Stack<of String> 
    871885        .bodiedBoxMemberDecls(theMixin) 
    872886        _boxStack.pop 
    873887 
     
    906920        theInterface = Interface(wordToken, idToken, name, .makeList<of IType>(genericParams), typeSpecs.isNames, typeSpecs.attributes, typeSpecs.inheritsProxies, docString) 
    907921 
    908922        _boxStack.push(theInterface) 
    909 #       .isNamesStack = Stack(str) 
    910923        .bodiedBoxMemberDecls(theInterface)  # TODO: this shouldn't be bodiedBoxMemberDecls, right? 
    911924        _boxStack.pop 
    912925 
     
    944957                .throwError('Cannot nest a type underneath a [parentBox.englishName]')  # TODO: needs a test case 
    945958 
    946959        _boxStack.push(theStruct) 
    947 #       .isNamesStack = Stack(str) 
    948960        .bodiedBoxMemberDecls(theStruct) 
    949961        _boxStack.pop 
    950962 
     
    15361548         
    15371549    def declareProperty as ProperDexer? 
    15381550        """ 
     1551        Parse full ('pro') form of a property (and indexer) 
    15391552        Example source 
    15401553            pro age as int 
    15411554                get 
     
    16391652            return prop 
    16401653 
    16411654    def declarePropertyFrom(token as IToken, idToken as IToken, name as String, coverWhat as String) as Property 
     1655        """Parse the 'from ...' form of pro/get/set property decl.""" 
    16421656        require coverWhat.isOneOf('get.set.getset.') 
    16431657        if .optional('VAR') 
    16441658            varName = '_' + name 
     
    16871701            varDef = possibleVarDef 
    16881702        else 
    16891703            .throwError('A property can only cover for variables. [varName] is a [possibleVarDef].')  # TODO: .englishName? 
     1704        # 'from varName' can only be on _ prefixed varnames otherwise cant resolve/rename the varName correctly 
     1705        if not varName.startsWith('_') 
     1706            sugg = 'You need "_[varName]" instead of "[varName]" or instead must use the full "pro...get...set" property declaration form.' 
     1707            .throwError('Explicitly specified property backing variable names must begin with an underscore prefix in the "from" form of a property. [sugg]') 
    16901708        if initExpr and not varDef.setInitExpr(initExpr to !)    
    16911709            .throwError('Property backing variable "[varName]" has already been initialized.') # include line# of backing variable decl 
    16921710        return varDef 
     
    16991717 
    17001718    def _declareGetOrSetOnlyProperty(getOrSet as int) as ProperDexer? 
    17011719        """ 
     1720        Parse shortcut forms (get and set) of property (and indexer) declarations. 
     1721         
    17021722        Example source 
    17031723            get meaningOfLife as int 
    17041724                return 42 
  • Tests/720-libraries/900-cobra-std-lib/300-list-as-stack.cobra

     
     1# test use of list as stack - push/pop RTL ExtendList.cobra 
     2class ListAsStack 
     3    def main is shared       
     4        t = [0] # [] as List<of int>  
     5        assert t.pop == 0 
     6        t.push(10) 
     7        assert t.count ==1 and t[0] == 10 
     8        t.push(11) 
     9        assert t.count == 2  
     10        assert t[0] == 10 and t[1] == 11 
     11        t.push(12) 
     12        assert t.count == 3  
     13        assert t[0] == 10 and t[1] == 11 and t[2] == 12 
     14        assert t.pop == 12 
     15        assert t.count == 2  and t[1] == 11 and t[0] == 10 
     16        t.push(21) 
     17        assert t.count == 3  and t[2] == 21 and t[1] == 11 and t[0] == 10 
     18        assert t.pop == 21 
     19        assert t.pop == 11 
     20        assert t.count ==1 and t[0] == 10 
     21        assert t.pop == 10 and t.count ==0 
     22        expect RequireException  
     23            t.pop 
     24         
     25        s = List<of String>() 
     26        s.push('hello') 
     27        s.push('mike') 
     28        assert s.count == 2 and s.last == 'mike' 
     29        s.push('.') 
     30        assert s.count ==3 and s.last == '.' 
     31        assert s.pop == '.' 
     32        assert s.count ==2 and s.last == 'mike' 
     33        s.push(',') 
     34        assert s.count ==3 and s.last == ',' 
     35        assert s.pop == ',' 
     36        assert s.count ==2 and s.last == 'mike' 
     37        assert s.pop == 'mike' 
     38        assert s.count == 1 and s[0] == 'hello' 
     39        s.clear 
     40 
     41        s = [ 'hi', 'haere mai', 'gidday'] 
     42        s.push('konnichiwa') 
     43        s.add('aloha') 
     44        c = s.count 
     45        s.pop 
     46        assert s.count == c-1 
     47        assert s.pop == 'konnichiwa' 
     48        assert s.pop == 'gidday' 
     49        assert s.pop == 'haere mai' 
     50        assert s.count == 1 and s.last == 'hi' 
     51        assert s.pop == 'hi' 
     52        expect RequireException  
     53            s.pop 
     54         
     55         
  • Tests/820-errors/400-declarations/420-accessor-err.cobra

     
     1# accessor error: both nonvirtual and override 
     2class AccessorTestB 
     3    def xx  
     4        print 'in AccessorTestB.xx' 
     5     
     6class AccessorTest inherits AccessorTestB 
     7    def xx is nonvirtual, override #.error. cannot specify both 
     8        print 'in xx' 
     9         
     10    def main is shared 
     11        x = AccessorTest() 
     12        x.xx 
  • Tests/820-errors/400-declarations/410-prop-pro-from-err.cobra

     
     1class MClass 
     2    var mlog = '' 
     3     
     4    cue init 
     5        base.init 
     6        .addLog('initializer called.')   
     7         
     8    def xx as String 
     9        v ='foo magoo.' 
     10        .addLog(v)  
     11        return v 
     12 
     13    def addLog(s as String) 
     14        .mlog += s  
     15        .mlog += '\n' 
     16         
     17    pro getLog from mlog  
     18    # .error. names must begin with an underscore prefix     
     19class EPoint 
     20    def main is shared 
     21        x = MClass() 
     22        print x.xx 
     23        print '- LOG -' 
     24        print x.getLog.trimEnd 
  • Tests/820-errors/400-declarations/422-prot-mod.cobra

     
     1class AccessorTest 
     2    def xx is private, protected #.error. can only specify one 
     3        pass 
     4     
     5    def xx1 is public, internal, protected  #.error. can only specify one 
     6        pass 
     7         
     8    def xx is public, private  #.error. can only specify one 
     9        pass 
     10         
     11    def xx is internal, private  #.error. can only specify one 
     12        pass 
     13         
     14    def xx is internal, public, private, protected   #.error. can only specify one 
     15        pass 
     16         
     17    def main is shared 
     18        x = AccessorTest() 
     19        x.xx 
  • Tests/820-errors/400-declarations/412-prop-get-from-err.cobra

     
     1class MClass 
     2    var mlog = '' 
     3     
     4    cue init 
     5        base.init 
     6        .addLog('initializer called.')   
     7         
     8    def xx as String 
     9        v ='foo magoo.' 
     10        .addLog(v)  
     11        return v 
     12 
     13    def addLog(s as String) 
     14        .mlog += s  
     15        .mlog += '\n' 
     16         
     17    #pro getLog as String 
     18    #   get 
     19    #       #print .mlog 
     20    #       return .mlog 
     21 
     22    get getLog from mlog  
     23    # .error. names must begin with an underscore prefix         
     24class EPoint 
     25    def main is shared 
     26        x = MClass() 
     27        print x.xx 
     28        print '- LOG -' 
     29        print x.getLog.trimEnd