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
2252 2252 2253 2253 def ifStmt as Stmt 2254 2254 token = .expect('IF') 2255 cond = .expression2255 cond = _expressionMultiLinePreBlock # was .expression 2256 2256 trueStmts = .block 2257 2257 falseStmts as BlockStmt? 2258 2258 if .peek.which=='ELSE' … … 2297 2297 def postWhileStmt as Stmt 2298 2298 token = .expect('POST') 2299 2299 .expect('WHILE') 2300 return PostWhileStmt(token, .expression, .block)2300 return PostWhileStmt(token, _expressionMultiLinePreBlock, .block) 2301 2301 2302 2302 def traceStmt as TraceStmt? 2303 2303 """ … … 2495 2495 return UsingStmt(token, varr, initExpr, block) 2496 2496 2497 2497 def whileStmt as Stmt 2498 return WhileStmt(.expect('WHILE'), .expression, .block)2498 return WhileStmt(.expect('WHILE'), _expressionMultiLinePreBlock, .block) 2499 2499 2500 2500 def yieldStmt as Stmt 2501 2501 token = .expect('YIELD') … … 2708 2708 2709 2709 var _inExpression as int 2710 2710 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 2711 2731 def expression as Expr 2712 2732 test 2713 2733 assert 0 not in _binaryOpPrec.values … … 2787 2807 # support foo.bar where bar is a keyword. Ex: foo.this 2788 2808 right = MemberExpr(.grab) to Expr 2789 2809 else 2790 right = .expression(prec)2810 right = _continuedExpression(prec, opToken to !) 2791 2811 if op == 'ASSIGN' and left inherits IdentifierExpr and (left to IdentifierExpr).name.startsWithNonLowerLetter 2792 2812 .recordError(ErrorMessages.localVariablesMustStartLowercase) 2793 2813 if op == 'DOT' and not right inherits IDotRightExpr … … 2923 2943 else 2924 2944 throw 2925 2945 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 2926 2967 def multiTargetAssign(arg0 as Expr) as Stmt 2927 2968 # id, |[id,]... = <expr> 2928 2969 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) 3 class 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