mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-19 15:31:28 +00:00
fixes #6609; 'if' expressions support multiple statements; minor breaking change
This commit is contained in:
15
changelog.md
15
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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user