fixes #6609; 'if' expressions support multiple statements; minor breaking change

This commit is contained in:
Araq
2017-11-05 01:25:39 +01:00
parent 9212aa9c0c
commit 742f43e572
5 changed files with 91 additions and 17 deletions

View File

@@ -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)

View File

@@ -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:

View File

@@ -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)

View File

@@ -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

View File

@@ -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