fixes #6609; 'if' expressions support multiple statements; minor breaking change
This commit is contained in:
parent
9212aa9c0c
commit
742f43e572
5 changed files with 91 additions and 17 deletions
13
changelog.md
13
changelog.md
|
|
@ -41,3 +41,16 @@
|
||||||
what to return if the environment variable does not exist.
|
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.
|
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
|
#| 'else' colcom expr
|
||||||
#| ifExpr = 'if' condExpr
|
#| ifExpr = 'if' condExpr
|
||||||
#| whenExpr = 'when' condExpr
|
#| whenExpr = 'when' condExpr
|
||||||
result = newNodeP(kind, p)
|
when true:
|
||||||
while true:
|
result = newNodeP(kind, p)
|
||||||
getTok(p) # skip `if`, `elif`
|
while true:
|
||||||
var branch = newNodeP(nkElifExpr, p)
|
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))
|
addSon(branch, parseExpr(p))
|
||||||
colcom(p, branch)
|
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))
|
addSon(branch, parseExpr(p))
|
||||||
optInd(p, branch)
|
result.add branch
|
||||||
addSon(result, branch)
|
while sameInd(p) or not wasIndented:
|
||||||
if p.tok.tokType != tkElif: break
|
case p.tok.tokType
|
||||||
var branch = newNodeP(nkElseExpr, p)
|
of tkElif:
|
||||||
eat(p, tkElse)
|
b = newNodeP(nkElifExpr, p)
|
||||||
colcom(p, branch)
|
getTok(p)
|
||||||
addSon(branch, parseExpr(p))
|
optInd(p, b)
|
||||||
addSon(result, branch)
|
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 =
|
proc parsePragma(p: var TParser): PNode =
|
||||||
#| pragma = '{.' optInd (exprColonExpr comma?)* optPar ('.}' | '}')
|
#| pragma = '{.' optInd (exprColonExpr comma?)* optPar ('.}' | '}')
|
||||||
|
|
@ -2036,8 +2073,13 @@ proc parseStmt(p: var TParser): PNode =
|
||||||
if a.kind != nkEmpty:
|
if a.kind != nkEmpty:
|
||||||
addSon(result, a)
|
addSon(result, a)
|
||||||
else:
|
else:
|
||||||
parMessage(p, errExprExpected, p.tok)
|
# This is done to make the new 'if' expressions work better.
|
||||||
getTok(p)
|
# 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
|
if not p.hasProgress and p.tok.tokType == tkEof: break
|
||||||
else:
|
else:
|
||||||
# the case statement is only needed for better error messages:
|
# 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:
|
if arg.valid:
|
||||||
let htmlOut = if isObject:
|
let htmlOut = if isObject:
|
||||||
"<object data=\"$1\" type=\"image/svg+xml\"$2 >" & content & "</object>"
|
"<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}",
|
dispA(d.target, result, htmlOut, "\\includegraphics$2{$1}",
|
||||||
[arg, options])
|
[arg, options])
|
||||||
if len(n) >= 3: renderRstToOut(d, n.sons[2], result)
|
if len(n) >= 3: renderRstToOut(d, n.sons[2], result)
|
||||||
|
|
|
||||||
|
|
@ -509,7 +509,7 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
|
||||||
|
|
||||||
# insert exponent
|
# insert exponent
|
||||||
t[ti] = 'E'; inc(ti)
|
t[ti] = 'E'; inc(ti)
|
||||||
t[ti] = if exp_negative: '-' else: '+'; inc(ti)
|
t[ti] = (if exp_negative: '-' else: '+'); inc(ti)
|
||||||
inc(ti, 3)
|
inc(ti, 3)
|
||||||
|
|
||||||
# insert adjusted exponent
|
# insert adjusted exponent
|
||||||
|
|
|
||||||
|
|
@ -32,3 +32,21 @@ let other = x:
|
||||||
echo "no"
|
echo "no"
|
||||||
let outer = y(5):
|
let outer = y(5):
|
||||||
echo "yes"
|
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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue