Wiki

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

File implicit-line-cont-expr2.patch, 6.4 KB (added by hopscc, 14 years ago)
  • Source/CobraParser.cobra

     
    22522252 
    22532253    def ifStmt as Stmt 
    22542254        token = .expect('IF') 
    2255         cond = .expression 
     2255        cond = _expressionMultiLinePreBlock     # was .expression 
    22562256        trueStmts = .block 
    22572257        falseStmts as BlockStmt? 
    22582258        if .peek.which=='ELSE' 
     
    22972297    def postWhileStmt as Stmt 
    22982298        token = .expect('POST') 
    22992299        .expect('WHILE') 
    2300         return PostWhileStmt(token, .expression, .block) 
     2300        return PostWhileStmt(token, _expressionMultiLinePreBlock, .block) 
    23012301 
    23022302    def traceStmt as TraceStmt? 
    23032303        """ 
     
    24952495        return UsingStmt(token, varr, initExpr, block) 
    24962496 
    24972497    def whileStmt as Stmt 
    2498         return WhileStmt(.expect('WHILE'), .expression, .block) 
     2498        return WhileStmt(.expect('WHILE'), _expressionMultiLinePreBlock, .block) 
    24992499 
    25002500    def yieldStmt as Stmt 
    25012501        token = .expect('YIELD') 
     
    27082708 
    27092709    var _inExpression as int 
    27102710     
     2711    def _expressionMultiLinePreBlock as Expr 
     2712        """ 
     2713        Special handling for expressions in some statements that may have a multiline/continued expression  
     2714            prior to an indented block. 
     2715        Ensures a statement that has hanging unpaired indents/dedents from removing indents in a multiline 
     2716            expression cleaned up and has the expected trailing EOL and INDENT after the expression. 
     2717        """ 
     2718        cond = .expression 
     2719        if  cond.token.lineNum <> .last.lineNum  and _spaceAgnosticIndentLevel <> 0 
     2720            # expression is broken across multiple lines and changed indentation 
     2721            # unwind indentation and correct indentation tokens for the expected following block 
     2722            _spaceAgnostic 
     2723            _spaceAgnosticIndentLevel=0 
     2724            if .peek.which <> 'COMMA' 
     2725                .ungrab 
     2726                .replace(.peek.copy('INDENT')) 
     2727                .ungrab 
     2728                .replace(.peek.copy('EOL')) 
     2729        return cond 
     2730         
    27112731    def expression as Expr 
    27122732        test 
    27132733            assert 0 not in _binaryOpPrec.values 
     
    27872807                        # support foo.bar where bar is a keyword. Ex: foo.this 
    27882808                        right = MemberExpr(.grab) to Expr 
    27892809                    else 
    2790                         right = .expression(prec) 
     2810                        right = _continuedExpression(prec, opToken to !) 
    27912811                    if op == 'ASSIGN' and left inherits IdentifierExpr and (left to IdentifierExpr).name.startsWithNonLowerLetter 
    27922812                        .recordError(ErrorMessages.localVariablesMustStartLowercase) 
    27932813                    if op == 'DOT' and not right inherits IDotRightExpr 
     
    29232943                        else 
    29242944                            throw 
    29252945 
     2946    var _implicitContinuationOps = [ 
     2947        'ASSIGN', 'AND', 'OR', 'STAR', 'SLASH', 'PLUS', 'MINUS', 
     2948        'EQ', 'NE', 'LT', 'GT', 'LE', 'GE', 'IN', 'NOTIN',   
     2949        'PLUS_EQUALS', 'MINUS_EQUALS', 'STAR_EQUALS', 'SLASH_EQUALS', 'PERCENT_EQUALS',  
     2950        'SLASHSLASH', 'PERCENT', 'AMPERSAND', 'VERTICAL_BAR',   'CARET', 'DOUBLE_LT',    
     2951        'DOUBLE_GT', 'AMPERSAND_EQUALS', 'VERTICAL_BAR_EQUALS', 'CARET_EQUALS',  
     2952        'DOUBLE_LT_EQUALS', 'DOUBLE_GT_EQUALS', 'STARSTAR', 'STARSTAR_EQUALS'  
     2953    ] 
     2954             
     2955    def _continuedExpression(prec as int, opToken as IToken) as Expr 
     2956        """ 
     2957        Handle expression that may end in line with an implicit continuation character 
     2958        Relies on _expressionMultilinePreBlock (on if, postwhile and while stmts) 
     2959        and end of statement _finishSpaceAgnostic to handle subsequent indent/dedent cleanup 
     2960        """ 
     2961        if .peek.which == 'EOL' and opToken.which in _implicitContinuationOps  
     2962            _spaceAgnostic # eat the following EOL and remove any now hanging indents 
     2963        right = .expression(prec) 
     2964        return right 
     2965         
     2966         
    29262967    def multiTargetAssign(arg0 as Expr) as Stmt 
    29272968        # id, |[id,]... = <expr> 
    29282969        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        .cond 
     7        .stmtExpr 
     8     
     9    def stmtExpr 
     10        assert 1 + 2 == 3       # ok 
     11             
     12        assert (1 +     # braces ok 
     13            2) == 3 
     14        assert (1 +     # braces ok 
     15            2)  
     16        assert 1 *      # implicit trailing '*', 0 indent 
     17        2  == 2 
     18         
     19        assert 1 +      # implicit trailing '+', 1 indent 
     20            2 == 3 
     21        #assert (1 +        # Ticket 210: Cannot mix tabs and spaces in indentation. 
     22        #      2) 
     23        #assert 1 +     # Both tickets. 
     24        #     2 == 3 
     25         
     26        assert (1 +     # braces, double indent 
     27                12) == 13 
     28        assert 1 +      # trailing '+', double indent after 
     29                2 == 3 
     30        assert 3 -      # trailing '-', double indent after 
     31                2 == 1 
     32                 
     33        assert 3 *      # ((3*1) + 4) -(8/2)  # multiple lines 
     34            1 + 
     35            4 - 
     36            8 / 
     37            2 == 3 
     38             
     39        a = 1 
     40        b = 2 
     41        assert (a == 1 and   
     42            b == 2) 
     43        assert a == 1 and   #implicit on 'and' 
     44            b == 2 
     45        assert a == 1 or    # implicit on or 
     46            b == 2 
     47 
     48        #assert a == 1 and  # implicit on and and tabs+spaces 
     49        #      b == 2 
     50 
     51 
     52    def cond 
     53        a=99 
     54        b=99 
     55         
     56         
     57        # expect these two to be the most common multiline condition indentation 
     58        # 2nd and perhaps subsequent lines indented 1 or 2 indents 
     59        if  a > 98 and 
     60            b == 99  
     61            assert true, 'OK - 1 indent' 
     62        else 
     63            assert false, 'fail' 
     64 
     65        if  a > 98 and 
     66                b == 99  
     67            assert true, 'OK - 2 indents' 
     68        else 
     69            assert false, 'fail' 
     70 
     71        if  a > 98 and 
     72            b == 99 or 
     73            a == b 
     74            assert true, 'OK - 1 indent' 
     75        else 
     76            assert false, 'fail' 
     77             
     78        if  a > 98 and 
     79                b == 99 or 
     80                a == b or 
     81                b > 45 
     82            assert true, 'OK - 2 indents' 
     83        else 
     84            assert false, 'fail' 
     85         
     86             
     87        if a > 98 and 
     88        b == 99     # no or matching indent - otherwise OK 
     89            assert true, 'OK - 0' 
     90        else, assert false, 'fail' 
     91         
     92        if  a > 98 and 
     93                        b == 99 
     94            assert true, 'OK - 4 indents' 
     95        else 
     96            assert false, 'fail' 
     97 
     98             
     99        if  a > 98 and  b == 99, assert true, 'OK - 2'  
     100        else, assert false, 'fail' 
     101 
     102        /# TODO Fix this case 
     103        if  a > 98 and 
     104            b == 99, assert true, 'OK - 2' 
     105        else, assert true, 'fail' 
     106        #/ 
     107         
     108        # pathological back indentation 
     109        if  a > 98 and 
     110    b == 99  
     111            assert true, 'OK - 1 DEDENT)' 
     112        else 
     113            assert false, 'fail' 
     114         
     115        # non multiline  
     116        if b==99 or a==99 
     117            assert true, 'normal'    
     118             
     119        if b==99 or a==99, assert true, 'normal'     
     120