Wiki

Ticket #31: implicitLineContInParens.patch

File implicitLineContInParens.patch, 10.0 KB (added by hopscc, 16 years ago)
  • Source/CobraParser.cobra

     
    100100    var _curCodePart as AbstractMethod? 
    101101 
    102102    var _spaceAgnosticIndentLevel as int 
     103    var _spaceAgnosticExprLevel as int 
    103104    var _isContractOnSameLine as bool 
    104105 
    105106    var _isTraceOn as bool 
     
    11891190            hasIsNames = true 
    11901191        else 
    11911192            .endOfLine 
    1192         if not .optional('INDENT') 
    1193             # with no indent there can be no additional specs like attributes, contracts or body 
     1193 
     1194        if _noMoreSpecs()   
     1195            # No additional specs like attributes, contracts or body 
    11941196            nothingMore = true 
    11951197            if not hasIsNames 
    11961198                isNames = List<of String>(_isNamesStack) 
     
    12391241        else 
    12401242            return method 
    12411243 
     1244    def _noMoreSpecs as bool 
     1245        """ 
     1246        Return a bool indicating that there is no (correctly indented) additional specs  
     1247        like attributes, contracts or body following. 
     1248        """ 
     1249        noMoreSpecs = false 
     1250        if _spaceAgnosticIndentLevel == 0           # paramdecls all on same line  
     1251            noMoreSpecs = not .optional('INDENT')   # Anything else must be indented 
     1252        else 
     1253            #print "[name] sail=[_spaceAgnosticIndentLevel] " 
     1254            sail = _spaceAgnosticIndentLevel 
     1255            if sail > 0 
     1256                _spaceAgnosticIndentLevel -= 1  # for missing indent 
     1257            _finishSpaceAgnostic 
     1258            if sail >= 1 
     1259                noMoreSpecs =  .optional('DEDENT') <> nil  
     1260            else 
     1261                noMoreSpecs = not .optional('INDENT') 
     1262 
     1263        #print "noMoreSpex=[noMoreSpecs]" 
     1264        return noMoreSpecs   
     1265                 
     1266                 
    12421267    def declareMethodSig as MethodSig 
    12431268        require _typeProvider 
    12441269        token = .expect('SIG') 
     
    15301555    ## 
    15311556 
    15321557    def paramDecls(skipParen as bool) as List<of Param> 
    1533         return .paramDecls(skipParen, 'RPAREN') 
     1558        return .paramDecls(skipParen, 'RPAREN', true) 
    15341559 
    15351560    def paramDecls(skipParen as bool, rightParen as String) as List<of Param> 
     1561        return .paramDecls(skipParen, rightParen, false)  
     1562         
     1563    def paramDecls(skipParen as bool, rightParen as String, isSpaceAgnostic as bool) as List<of Param> 
    15361564        if not skipParen 
    15371565            .expect('LPAREN') 
    15381566        params = List<of Param>() 
    15391567        expectComma = false 
    15401568        while true 
     1569            if isSpaceAgnostic 
     1570                _spaceAgnostic 
    15411571            if .peek.which==rightParen 
    15421572                .grab 
    15431573                break 
    15441574            if expectComma 
    15451575                .expect('COMMA') 
     1576            if isSpaceAgnostic 
     1577                _spaceAgnostic 
    15461578            param = .paramDecl 
    15471579            params.add(param) 
    15481580            if params.count==1 and param.name=='self' and param.isMissingType 
     
    23632395            _inExpression += 1 
    23642396            try 
    23652397                expr = .expression(0, nil) 
    2366                 if expr.isParened 
     2398                if expr.isParened and expr.token.lineNum == .last.lineNum 
    23672399                    _warning(expr.token, 'Unnecessary parentheses around expression. You can remove them.') 
    23682400                return expr 
    23692401            finally 
     
    23982430                if not PostCallExpr.isTargetAcceptable(left to !) 
    23992431                    .throwError('Unexpected call.')  # example: t = x to List<of String>() 
    24002432                token = .grab 
     2433                #exprs = .commaSepExprs(['RPAREN'], true, false) 
    24012434                exprs = .commaSepExprs('RPAREN') 
    24022435                return .expression(precedence, PostCallExpr(token, left, exprs)) 
    24032436            else 
     
    24442477        return left to ! 
    24452478 
    24462479    def expression2 as Expr 
     2480        if _spaceAgnosticExprLevel > 0 #and .peek.which in ['EOL','INDENT','DEDENT'] 
     2481            _spaceAgnostic 
    24472482        peekToken = .peek 
    24482483        peek = peekToken.which 
    24492484        if _unaryOpPrec.containsKey(peek) 
     
    24602495        # TODO: make a branch statement 
    24612496        else if peek=='LPAREN' 
    24622497            .grab 
     2498            _spaceAgnosticExprLevel += 1 
    24632499            node = .expression(0, nil) 
    24642500            .expect('RPAREN') 
     2501            _spaceAgnosticExprLevel -= 1 
    24652502            node.isParened = true 
    24662503            return node 
    24672504        else if peek=='DOT' 
     
    25442581                return .typeExpr 
    25452582            catch pe as ParserException 
    25462583                if pe.message.contains('Unrecognized type') 
    2547                     msg = 'Expecting an expression.' 
     2584                    ofst = pe.message.indexOf('Unrecognized type') 
     2585                    submsg = pe.message[ofst:] 
     2586                    msg = '[submsg] Expecting an expression.' 
    25482587                    if peekToken.isKeyword 
    25492588                        msg += ' "[peekToken.text]" is a reserved keyword that is not expected here.' 
    25502589                    .throwError(msg) 
     
    25622601        branch token.which 
    25632602            on 'OPEN_CALL' 
    25642603                assert not callName.endsWith('(') 
    2565                 args = .commaSepExprs(['RPAREN'], false, true) 
     2604                args = .commaSepExprs(['RPAREN'], true, true) # false, true) 
    25662605                return CallExpr(token, callName, args) 
    25672606            on 'OPEN_GENERIC' 
    25682607                assert not callName.endsWith('<of') and not callName.endsWith('<') 
     
    25752614                        on 'GT', isDone = true 
    25762615                        else, .throwError('Unexpected token [.last] in type arguments.') 
    25772616                .expect('LPAREN') 
    2578                 args = .commaSepExprs(['RPAREN'], false, true) 
     2617                args = .commaSepExprs(['RPAREN'], true, true) #false, true) 
    25792618                return CallExpr(token, callName, typeArgs, args) 
    25802619            else 
    25812620                throw FallThroughException(token)                
     
    31983237                    _spaceAgnosticIndentLevel -= 1 
    31993238                    continue 
    32003239            break 
     3240        if _verbosity>=5 
     3241            print '<> spaceAgnostic level=[_spaceAgnosticIndentLevel]' 
    32013242 
    32023243    def _finishSpaceAgnostic 
    32033244        """ 
  • Tests/110-basics-two/920-space-agnostic-expr.cobra

     
     1# Simple Test for implicit line continuation in paren delimited expressions 
     2 
     3namespace Test 
     4    class SpaceAgnostic 
     5     
     6        def main is shared 
     7            i = (100 + 1 + 2 + 
     8                3 + 4) 
     9            #print i 
     10            assert i == 110 
     11            s = ('a very long line of text ' + 
     12                'another long line') 
     13            #print s 
     14            assert s == 'a very long line of text another long line' 
     15             
     16            i = (100 + 1 + 2 + 
     17                    3 + 4) 
     18            assert i == 110 
     19                     
     20            # TODO add more 
  • Tests/110-basics-two/910-space-agnostic-method.cobra

     
     1# Simple Test for implicit line continuation in method call arglists  and  
     2# method param declarations 
     3# if this fails it probably wont compile 
     4namespace Test 
     5    class SpaceAgnostic 
     6     
     7        def main is shared 
     8            CobraCore.tracer.isActive = false 
     9            .foo('foo argument Number 1', 
     10                'arg2', 
     11                'areg3' ) 
     12                 
     13            .foo2('foo2 argument Number 1', 
     14                    'argument Number 2', 
     15                    'argument Number THree reg3' ) 
     16                 
     17            .foo3('foo3 argument Number 1', 
     18                        'argument Number 2',  
     19                        'argument Number THree reg3' ) 
     20 
     21            .foo4('foo4 argument Number 1',  
     22            'argument Number 2',  
     23            'argument Number THree reg3' ) 
     24 
     25            .foo5('foo5 argument Number 1',  
     26        'argument Number 2',  
     27            'argument Number THree reg3' ) 
     28             
     29            .foo6('foo6 argument Number 1',  
     30                    'argument Number 2',  
     31                'argument Number THree reg3' ) 
     32             
     33            .foo7('foo7 argument Number 1',  
     34                        'argument Number 2',  
     35            'argument Number THree reg3' ) 
     36            # thats it for calls 
     37         
     38        def foo(arg1 as String, arg2 as String, arg3 as String) is shared 
     39            assert arg1.length 
     40            #print 'foo done' 
     41             
     42        def foo2(arg1 as String,  
     43                arg2 as String,  
     44                arg3 as String  ) is shared 
     45            assert arg1.length 
     46            trace arg1 
     47            assert arg1.length 
     48            trace arg2 
     49            assert arg2.length 
     50            trace arg3 
     51            assert arg3.length 
     52            #print 'foo2 done' 
     53         
     54        def foo2a(arg1 as String,  
     55                    arg2 as String,  
     56                    arg3 as String  ) is shared 
     57            assert arg1.length 
     58            trace arg1 
     59            assert arg1.length 
     60            trace arg2 
     61            assert arg2.length 
     62            trace arg3 
     63            assert arg3.length 
     64            #print 'foo2a done' 
     65             
     66        def foo3(arg1 as String,  
     67            arg2 as String,  
     68            arg3 as String  ) is shared 
     69            assert arg1.length 
     70            trace arg1 
     71            assert arg1.length 
     72            trace arg2 
     73            assert arg2.length 
     74            trace arg3 
     75            assert arg3.length 
     76            #print 'foo3 done' 
     77         
     78        # pathological (0) 
     79        def foo4(arg1 as String,  
     80        arg2 as String,  
     81        arg3 as String  ) is shared 
     82            assert arg1.length 
     83            #print "in foo4" 
     84            trace arg1 
     85            assert arg1.length 
     86            trace arg2 
     87            assert arg2.length 
     88            trace arg3 
     89            assert arg3.length 
     90            #print 'foo4 done' 
     91         
     92        # pathological (+1) 
     93        def foo5(arg1 as String,  
     94    arg2 as String,  
     95    arg3 as String  ) is shared 
     96            #print "in foo5" 
     97            trace arg1 
     98            assert arg1.length 
     99            trace arg2 
     100            assert arg2.length 
     101            trace arg3 
     102            assert arg3.length 
     103            #print 'foo5 done' 
     104         
     105        # pathological (++1) 
     106        def foo6(arg1 as String,  
     107arg2 as String,  
     108arg3 as String  ) is shared 
     109            trace arg1 
     110            assert arg1.length 
     111            trace arg2 
     112            assert arg2.length 
     113            trace arg3 
     114            assert arg3.length 
     115            #print 'foo6 done' 
     116         
     117        def foo7(arg1 as String,  
     118                        arg2 as String,  
     119                        arg3 as String  ) is shared 
     120            trace arg1 
     121            assert arg1.length 
     122            trace arg2 
     123            assert arg2.length 
     124            trace arg3 
     125            assert arg3.length 
     126            #print 'foo7 done' 
     127             
     128    class AbX  
     129        is abstract  
     130 
     131        def aa(arg1 as String) is abstract 
     132             
     133        def ab(arg1 as String,   
     134                    arg2 as String) is abstract 
     135        def ac(arg1 as String, 
     136            arg2 as String) is abstract 
     137             
     138        def ad(arg1 as String, 
     139        arg2 as String) is abstract 
     140     
     141        def ad1(arg1 as String, 
     142    arg2 as String) is abstract 
     143         
     144        def ae(arg1 as String, 
     145            arg2 as String) is abstract 
  • Developer/IntermediateReleaseNotes.text

     
    11Post 0.8 
    22 
     3* Added support for implicit line continuation for items in parentheses. 
     4 i.e method call argument lists, method declaration parameters and  
     5     parenthesised expressions. 
     6 
    37* Added a new built-in doc tool accessible via "cobra -doc ...". The documentation is generated to local HTML files using your declarations, doc strings, contracts, etc. 
    48 
    59* Add support for specifying unsigned integers as Hex literals