diff options
-rw-r--r-- | changelog.md | 15 | ||||
-rw-r--r-- | compiler/parser.nim | 70 | ||||
-rw-r--r-- | lib/packages/docutils/rstgen.nim | 3 | ||||
-rw-r--r-- | lib/system/sysstr.nim | 2 | ||||
-rw-r--r-- | tests/parser/tletcolon.nim | 18 |
5 files changed, 91 insertions, 17 deletions
diff --git a/changelog.md b/changelog.md index eebd47fb8..5947c49e5 100644 --- a/changelog.md +++ b/changelog.md @@ -39,5 +39,18 @@ - Added ``typetraits.$`` as an alias for ``typetraits.name``. - ``os.getEnv`` now takes an optional ``default`` parameter that tells ``getEnv`` what to return if the environment variable does not exist. -- Removed PDCurses wrapper from the stdlib and published it as a separate +- Removed PDCurses wrapper from the stdlib and published it as a separate Nimble package. +- The parsing rules of ``if`` expressions were changed so that multiple + statements are allowed in the branches. We found few code examples that + now fail because of this change, but here is one: + +.. code-block:: nim + + t[ti] = if exp_negative: '-' else: '+'; inc(ti) + +This now needs to be written as: + +.. code-block:: nim + + t[ti] = (if exp_negative: '-' else: '+'); inc(ti) diff --git a/compiler/parser.nim b/compiler/parser.nim index 113922189..e3bb68da4 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -785,21 +785,58 @@ proc parseIfExpr(p: var TParser, kind: TNodeKind): PNode = #| 'else' colcom expr #| ifExpr = 'if' condExpr #| whenExpr = 'when' condExpr - result = newNodeP(kind, p) - while true: - getTok(p) # skip `if`, `elif` - var branch = newNodeP(nkElifExpr, p) + when true: + result = newNodeP(kind, p) + while true: + getTok(p) # skip `if`, `when`, `elif` + var branch = newNodeP(nkElifExpr, p) + optInd(p, branch) + addSon(branch, parseExpr(p)) + colcom(p, branch) + addSon(branch, parseStmt(p)) + skipComment(p, branch) + addSon(result, branch) + if p.tok.tokType != tkElif: break # or not sameOrNoInd(p): break + if p.tok.tokType == tkElse: # and sameOrNoInd(p): + var branch = newNodeP(nkElseExpr, p) + eat(p, tkElse) + colcom(p, branch) + addSon(branch, parseStmt(p)) + addSon(result, branch) + else: + var + b: PNode + wasIndented = false + result = newNodeP(kind, p) + + getTok(p) + let branch = newNodeP(nkElifExpr, p) addSon(branch, parseExpr(p)) colcom(p, branch) + let oldInd = p.currInd + if realInd(p): + p.currInd = p.tok.indent + wasIndented = true + echo result.info, " yes ", p.currInd addSon(branch, parseExpr(p)) - optInd(p, branch) - addSon(result, branch) - if p.tok.tokType != tkElif: break - var branch = newNodeP(nkElseExpr, p) - eat(p, tkElse) - colcom(p, branch) - addSon(branch, parseExpr(p)) - addSon(result, branch) + result.add branch + while sameInd(p) or not wasIndented: + case p.tok.tokType + of tkElif: + b = newNodeP(nkElifExpr, p) + getTok(p) + optInd(p, b) + addSon(b, parseExpr(p)) + of tkElse: + b = newNodeP(nkElseExpr, p) + getTok(p) + else: break + colcom(p, b) + addSon(b, parseStmt(p)) + addSon(result, b) + if b.kind == nkElseExpr: break + if wasIndented: + p.currInd = oldInd proc parsePragma(p: var TParser): PNode = #| pragma = '{.' optInd (exprColonExpr comma?)* optPar ('.}' | '}') @@ -2036,8 +2073,13 @@ proc parseStmt(p: var TParser): PNode = if a.kind != nkEmpty: addSon(result, a) else: - parMessage(p, errExprExpected, p.tok) - getTok(p) + # This is done to make the new 'if' expressions work better. + # XXX Eventually we need to be more strict here. + if p.tok.tokType notin {tkElse, tkElif}: + parMessage(p, errExprExpected, p.tok) + getTok(p) + else: + break if not p.hasProgress and p.tok.tokType == tkEof: break else: # the case statement is only needed for better error messages: diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index 13016bfc0..6fed40141 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -798,7 +798,8 @@ proc renderImage(d: PDoc, n: PRstNode, result: var string) = if arg.valid: let htmlOut = if isObject: "<object data=\"$1\" type=\"image/svg+xml\"$2 >" & content & "</object>" - else: "<img src=\"$1\"$2 />" + else: + "<img src=\"$1\"$2 />" dispA(d.target, result, htmlOut, "\\includegraphics$2{$1}", [arg, options]) if len(n) >= 3: renderRstToOut(d, n.sons[2], result) diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim index 0627ef2fb..d9586b00d 100644 --- a/lib/system/sysstr.nim +++ b/lib/system/sysstr.nim @@ -509,7 +509,7 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat, # insert exponent t[ti] = 'E'; inc(ti) - t[ti] = if exp_negative: '-' else: '+'; inc(ti) + t[ti] = (if exp_negative: '-' else: '+'); inc(ti) inc(ti, 3) # insert adjusted exponent diff --git a/tests/parser/tletcolon.nim b/tests/parser/tletcolon.nim index 6b86535c8..eab7a8edd 100644 --- a/tests/parser/tletcolon.nim +++ b/tests/parser/tletcolon.nim @@ -32,3 +32,21 @@ let other = x: echo "no" let outer = y(5): echo "yes" + + +# bug #6609 +type + TextureInternalFormat = enum RED, RGB, RGBA + +const channels = 4 + +let format = + if channels == 1: + TextureInternalFormat.RED + elif channels == 3: + TextureInternalFormat.RGB + elif channels == 4: + TextureInternalFormat.RGBA + else: + echo "Texture Format Unknown, assuming RGB" #This echo causes an error + TextureInternalFormat.RGB |