Ticket #273: tweaks.patch
File tweaks.patch, 19.7 KB (added by hopscc, 14 years ago) |
---|
-
Source/Cobra.Lang/Extensions.cobra
6 6 extend System.Object 7 7 8 8 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 """ 10 13 return .getType 11 14 12 15 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 """ 13 23 return CobraImp._techStringMaker.makeString(this) 14 24 15 25 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 """ 16 31 return CobraImp._printStringMaker.makeString(this) 17 32 18 33 … … 38 53 return this[:1].toUpper + this[1:] 39 54 40 55 def count(c as char) as int 56 """Return a count of the number of occurrences of the char in this string.""" 41 57 test 42 58 assert ''.count(c'x')==0 43 59 assert 'x'.count(c'x')==1 … … 50 66 return count 51 67 52 68 def isCapitalized as bool 69 """Return a bool indicating if this string is nonzero length and starts with an uppercase letter.""" 53 70 test 54 71 assert 'Aoeu'.isCapitalized 55 72 assert 'Zaoeu'.isCapitalized … … 60 77 return .length and this[0].isUpper 61 78 62 79 def md5HashInHex as String 80 """Return a string of Hex characters of the md5 hash of this string.""" 63 81 ensure 64 82 result.length == 32 65 83 test … … 81 99 return .split(separator, count, StringSplitOptions.None) 82 100 83 101 def split(separator as String, options as StringSplitOptions) as String[] 84 return .split(separator, 2_147_483_647, StringSplitOptions.None) # CC: int.max102 return .split(separator, 2_147_483_647, options) # CC: int.max 85 103 86 104 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 """ 87 109 require 88 110 count >= 0 89 111 test … … 103 125 return .split(@[separator], count, options) to ! 104 126 105 127 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.""" 106 129 test 107 130 s = 'a,b:c:d,e,f' 108 131 assert s.split([c',', c':']) == ['a', 'b', 'c', 'd', 'e', 'f'] … … 110 133 return List<of String>(.split(chars.toArray) to !) 111 134 112 135 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.""" 113 137 charsArray = char[](chars.count) 114 138 for i in chars.count, charsArray[i] = chars[i] 115 139 return List<of String>(.split(charsArray)) … … 120 144 def splitLines(keepEnds as bool) as List<of String> 121 145 """ 122 146 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. 123 148 """ 124 149 test 125 150 cases = [ … … 189 214 return lines 190 215 191 216 def splitWords as List<of String> 217 """Split this string int (non whitespace) words returning them as a list of strings.""" 192 218 test 193 219 # preliminary: 194 220 assert 'foo bar'.split == ['foo', 'bar'] -
Source/Cobra.Lang/ExtendIEnumerable.cobra
49 49 extend IEnumerable<of T> 50 50 51 51 def toList as List<of T> 52 """Turn an IEnumerable of T into a list of T.""" 52 53 return List<of T>(this) 53 54 /# 54 55 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
59 59 return newList 60 60 61 61 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 """ 62 69 require 63 70 .count > 0 64 71 (flexibleIndex >= 0 and flexibleIndex < .count) _ … … 68 75 return this[flexibleIndex] 69 76 70 77 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 """ 71 82 ensure 72 83 .count == 0 implies result == default 73 84 (flexibleIndex > .count or flexibleIndex < -.count) _ … … 114 125 yield KeyValuePair<of int, T>(index, this[index]) 115 126 116 127 def random as T 128 """Return an item at a random postion in the list""" 117 129 require .count > 0 118 130 return .random(CobraCore.random) 119 131 … … 122 134 return this[r.next % .count] 123 135 124 136 def removeLast 137 """Remove the last item in the list.""" 125 138 require .count > 0 126 139 ensure .count == old .count - 1 127 140 .removeAt(.count-1) 128 141 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 129 153 def reversed as List<of T> 154 """ Return a copy of this list reversed.""" 130 155 ensure 131 156 result is not this 132 157 result.count == .count … … 136 161 return t 137 162 138 163 def sorted as List<of T> 164 """ Return a copy of this list sorted.""" 139 165 ensure 140 166 result is not this 141 167 result.count == .count … … 252 278 else 253 279 expect ArgumentOutOfRangeException, t.last 254 280 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 255 305 # numbered 256 306 t = [10, 20, 30] 257 307 count = 0 -
Source/Node.cobra
4 4 class SubnodesAttribute inherits Attribute 5 5 """ 6 6 Put this attribute on properties that represent a collection of subnodes of the declaring node class. 7 Node.repl oceChild 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). 8 8 There may be other uses for this in the future. 9 9 The property value should respond to .indexOf(node) and "subnodes[index] = newNode" which are covered by List<of>. 10 10 Since dynamic binding is used, inheriting from List<of> is not strictly required. -
Source/CobraParser.cobra
1 1 """ 2 2 The 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). 3 7 4 8 Rules: 5 9 * Do not invoke Box.memberForName. Use Box.declForName instead. Inheritance relationships are not established during parsing. … … 90 94 var _uppercaseLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 91 95 92 96 var _isNamesStack as Stack<of String>? 97 """Stack for recording modifier for items in modifier sections (e.g.shared)""" 98 93 99 var _boxStack as Stack<of Box>? 100 """Stack to record the box the current level of box member decls is for.""" 94 101 95 102 var _globalNS as NameSpace? 96 103 var _nameSpaceStack as Stack<of NameSpace> … … 179 186 180 187 def parseSource(fileName as String, source as String) as CobraModule 181 188 """ 182 Parses module source code and returns resulting module.189 Parses module source code and returns resulting (cobra) module. 183 190 The fileName is recorded, but the file is not physically accessed. 184 191 After parsing, .references will hold a list of any @ref directive references that were parsed. 185 192 """ … … 199 206 200 207 def _preParseSource(fileName as String, source as String) as bool 201 208 """ 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`. 203 211 Used by `parseSource` and various test sections. 204 212 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. 206 214 Does not .throwError but may .recordError. 207 215 """ 208 216 _fileName = fileName … … 337 345 338 346 def _parseTokens as CobraModule 339 347 """ 340 Parses and then returns an instance of Module.348 Parses and then returns an instance of (Cobra)Module. 341 349 """ 342 350 .zeroOrMore('EOL') 343 351 docString = .docString … … 524 532 var _syntaxForClassInheritanceMsg = 'The syntax for inheritance is to put "inherits BaseClass" on the following line, indented.' 525 533 526 534 def assemblyDecl as AssemblyDecl 535 """ 536 Parse attribute entries for an assembly attributes declaration 537 """ 527 538 token = .expect('ID') 528 539 assert token.text == 'assembly' 529 540 .indent … … 674 685 .throwError('Cannot nest a type underneath a [parentBox.englishName]') # TODO: needs a test case 675 686 676 687 _boxStack.push(theClass) 677 # .isNamesStack = Stack<of String>678 688 .bodiedBoxMemberDecls(theClass) 679 689 _boxStack.pop 680 690 … … 751 761 """ 752 762 hasIsNames = false 753 763 names = _isDeclNamesNoEOL(out hasIsNames) 754 if hasIsNames 764 if hasIsNames 755 765 .endOfTypeSpecClause 756 # TODO: error on virtual and override757 # TODO: error on virtual and shared758 # TODO: error if 2 or more of 'public', 'protected', 'private', 'internal'759 766 return names 760 767 761 768 def _isDeclNamesNoEOL(hasIsNames as out bool) as List<of String> … … 781 788 if .peek.text in .validIsNames 782 789 .throwError(.peek, 'Multiple access modifiers should be separated by commas such as "[what], [.peek.text]".') 783 790 break 784 # TODO: error on virtual and override785 791 # 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".') 787 801 return names 788 802 789 803 var _validIsNames as List<of String>? 804 var _validProtModifiers = ['public', 'protected', 'private', 'internal'] 790 805 791 806 get validIsNames as List<of String> 792 807 if _validIsNames is nil … … 867 882 868 883 # TODO when supporting nested classes, look at the _boxStack and set a back pointer here 869 884 _boxStack.push(theMixin) 870 # .isNamesStack = Stack<of String>871 885 .bodiedBoxMemberDecls(theMixin) 872 886 _boxStack.pop 873 887 … … 906 920 theInterface = Interface(wordToken, idToken, name, .makeList<of IType>(genericParams), typeSpecs.isNames, typeSpecs.attributes, typeSpecs.inheritsProxies, docString) 907 921 908 922 _boxStack.push(theInterface) 909 # .isNamesStack = Stack(str)910 923 .bodiedBoxMemberDecls(theInterface) # TODO: this shouldn't be bodiedBoxMemberDecls, right? 911 924 _boxStack.pop 912 925 … … 944 957 .throwError('Cannot nest a type underneath a [parentBox.englishName]') # TODO: needs a test case 945 958 946 959 _boxStack.push(theStruct) 947 # .isNamesStack = Stack(str)948 960 .bodiedBoxMemberDecls(theStruct) 949 961 _boxStack.pop 950 962 … … 1536 1548 1537 1549 def declareProperty as ProperDexer? 1538 1550 """ 1551 Parse full ('pro') form of a property (and indexer) 1539 1552 Example source 1540 1553 pro age as int 1541 1554 get … … 1639 1652 return prop 1640 1653 1641 1654 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.""" 1642 1656 require coverWhat.isOneOf('get.set.getset.') 1643 1657 if .optional('VAR') 1644 1658 varName = '_' + name … … 1687 1701 varDef = possibleVarDef 1688 1702 else 1689 1703 .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]') 1690 1708 if initExpr and not varDef.setInitExpr(initExpr to !) 1691 1709 .throwError('Property backing variable "[varName]" has already been initialized.') # include line# of backing variable decl 1692 1710 return varDef … … 1699 1717 1700 1718 def _declareGetOrSetOnlyProperty(getOrSet as int) as ProperDexer? 1701 1719 """ 1720 Parse shortcut forms (get and set) of property (and indexer) declarations. 1721 1702 1722 Example source 1703 1723 get meaningOfLife as int 1704 1724 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 2 class 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 2 class AccessorTestB 3 def xx 4 print 'in AccessorTestB.xx' 5 6 class 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
1 class 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 19 class 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
1 class 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
1 class 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 24 class EPoint 25 def main is shared 26 x = MClass() 27 print x.xx 28 print '- LOG -' 29 print x.getLog.trimEnd