Wiki

Ticket #211: implicit-line-cont-expr.patch

File implicit-line-cont-expr.patch, 4.7 KB (added by hopscc, 14 years ago)
  • Source/Parser.cobra

     
    108108        ensure .peek == token 
    109109        _tokens[_nextTokenIndex] = token 
    110110         
     111    def drop(offset as int) 
     112        """ 
     113        Remove the token offset fwd in the token stream 
     114        """ 
     115        i = _nextTokenIndex + offset 
     116        if i < _tokens.count 
     117            #token = _tokens[i] to ? 
     118            #assert token.which == 'DEDENT' 
     119            _tokens.removeAt(i) 
     120 
    111121    def last as IToken? 
    112122        return .last(0) 
    113123 
  • Source/CobraParser.cobra

     
    27872787                        # support foo.bar where bar is a keyword. Ex: foo.this 
    27882788                        right = MemberExpr(.grab) to Expr 
    27892789                    else 
    2790                         right = .expression(prec) 
     2790                        right = _continuedExpression(prec, opToken to !) 
    27912791                    if op == 'ASSIGN' and left inherits IdentifierExpr and (left to IdentifierExpr).name.startsWithNonLowerLetter 
    27922792                        .recordError(ErrorMessages.localVariablesMustStartLowercase) 
    27932793                    if op == 'DOT' and not right inherits IDotRightExpr 
     
    27982798                _leftStack.pop 
    27992799        assert left 
    28002800        return left to ! 
    2801  
     2801         
    28022802    def expression2 as Expr 
    28032803        if _spaceAgnosticExprLevel > 0, _spaceAgnostic 
    28042804        peekToken = .peek 
     
    29232923                        else 
    29242924                            throw 
    29252925 
     2926    var _implicitContinuationOps = [ 
     2927        'ASSIGN', 'AND', 'OR', 'STAR', 'SLASH', 'PLUS', 'MINUS', 
     2928        'EQ', 'NE', 'LT', 'GT', 'LE', 'GE', 'IN', 'NOTIN',   
     2929        'PLUS_EQUALS', 'MINUS_EQUALS', 'STAR_EQUALS', 'SLASH_EQUALS', 'PERCENT_EQUALS',  
     2930        'SLASHSLASH', 'PERCENT', 'AMPERSAND', 'VERTICAL_BAR',   'CARET', 'DOUBLE_LT',    
     2931        'DOUBLE_GT', 'AMPERSAND_EQUALS', 'VERTICAL_BAR_EQUALS', 'CARET_EQUALS',  
     2932        'DOUBLE_LT_EQUALS', 'DOUBLE_GT_EQUALS', 'STARSTAR', 'STARSTAR_EQUALS'  
     2933    ] 
     2934             
     2935    def _continuedExpression(prec as int, opToken as IToken) as Expr 
     2936        """ 
     2937        Handle expression that may end in line with an implicit continuation character 
     2938        """ 
     2939        choppedIndents =0 
     2940        if .peek.which == 'EOL' and opToken.which in _implicitContinuationOps  
     2941            .grab   # eat the following EOL and remove any now hanging indents 
     2942            while .peek.which == 'INDENT'  
     2943                .grab 
     2944                choppedIndents += 1 
     2945        right = .expression(prec) 
     2946        if choppedIndents > 0  
     2947            # correct any following dedents for removed hanging indents 
     2948            choppedIndents =_eatNextDedents(choppedIndents) 
     2949        assert choppedIndents == 0 
     2950        return right 
     2951         
     2952    def _eatNextDedents(nDedents as int) as int 
     2953        """ 
     2954        Look fwd to next DEDENT and consume the following nDedents. 
     2955        Error if not enough dedents. 
     2956        Provides resync for indentation swallowed after an implicit line continuation character  
     2957        """ 
     2958        nDedents0 = nDedents 
     2959        ofset = 0 
     2960        while .peek(ofset).which <> 'DEDENT' 
     2961            ofset += 1  
     2962        while nDedents > 0 and .peek(ofset).which == 'DEDENT' 
     2963            .drop(ofset) 
     2964            nDedents -= 1 
     2965        if nDedents <> 0  
     2966            .throwError('After implicit line continuation wrong indentation. Expecting [nDedents0] sequential dedents but got only [nDedents0 - nDedents]') 
     2967        return nDedents 
     2968         
    29262969    def multiTargetAssign(arg0 as Expr) as Stmt 
    29272970        # id, |[id,]... = <expr> 
    29282971        args = .commaSepExprsPartial('ASSIGN.EOL.', 'ASSIGN') 
  • Tests/110-basics-two/150-line-continuation/120-implicit-line-cont-ops.cobra

     
     1# Test for implicit forms of line continuation: round brackets and trailing binary ops 
     2# ticket:211 (partially also addresses ticket 210) 
     3class Program 
     4 
     5    def main 
     6        assert 1 + 2 == 3       # ok 
     7             
     8        assert (1 +     # braces ok 
     9            2) == 3 
     10        assert 1 *      # implicit trailing '*', 0 indent 
     11        2  == 2 
     12         
     13        assert 1 +      # implicit trailing '+', 1 indent 
     14            2 == 3 
     15        #assert (1 +        # Ticket 210: Cannot mix tabs and spaces in indentation. 
     16        #      2) 
     17        #assert 1 +     # Both tickets. 
     18        #     2 == 3 
     19 
     20        assert (1 +     # braces, double indent 
     21                12) == 13 
     22        assert 1 +      # trailing '+', double indent after 
     23                2 == 3 
     24        assert 3 -      # trailing '-', double indent after 
     25                2 == 1 
     26                 
     27        assert 3 *      # ((3*1) + 4) -(8/2)  # multiple lines 
     28            1 + 
     29            4 - 
     30            8 / 
     31            2 == 3 
     32             
     33        a = 1 
     34        b = 2 
     35        assert (a == 1 and   
     36            b == 2) 
     37        assert a == 1 and   #implicit on 'and' 
     38            b == 2 
     39        assert a == 1 or    # implicit on or 
     40            b == 2 
     41 
     42        #assert a == 1 and  # implicit on and and tabs+spaces 
     43        #      b == 2 
     44 
     45