* allow result symbol reuse

* try different approach

* Revert "try different approach"

This reverts commit abcfb6b759.
This commit is contained in:
cooldome
2020-09-24 00:07:30 +01:00
committed by GitHub
parent fe3211fbcf
commit f21a49b2c4
3 changed files with 44 additions and 24 deletions

View File

@@ -1754,17 +1754,21 @@ proc semReturn(c: PContext, n: PNode): PNode =
if c.p.owner.kind in {skConverter, skMethod, skProc, skFunc, skMacro} or
(not c.p.owner.typ.isNil and isClosureIterator(c.p.owner.typ)):
if n[0].kind != nkEmpty:
# transform ``return expr`` to ``result = expr; return``
if c.p.resultSym != nil:
if n[0].kind == nkAsgn and n[0][0].kind == nkSym and c.p.resultSym == n[0][0].sym:
discard "return is already transformed"
elif c.p.resultSym != nil:
# transform ``return expr`` to ``result = expr; return``
var a = newNodeI(nkAsgn, n[0].info)
a.add newSymNode(c.p.resultSym)
a.add n[0]
n[0] = semAsgn(c, a)
# optimize away ``result = result``:
if n[0][1].kind == nkSym and n[0][1].sym == c.p.resultSym:
n[0] = c.graph.emptyNode
else:
n[0] = a
else:
localError(c.config, n.info, errNoReturnTypeDeclared)
return
result[0] = semAsgn(c, n[0])
# optimize away ``result = result``:
if result[0][1].kind == nkSym and result[0][1].sym == c.p.resultSym:
result[0] = c.graph.emptyNode
else:
localError(c.config, n.info, "'return' not allowed here")

View File

@@ -1430,16 +1430,19 @@ proc semBorrow(c: PContext, n: PNode, s: PSym) =
else:
localError(c.config, n.info, errNoSymbolToBorrowFromFound)
proc addResult(c: PContext, t: PType, info: TLineInfo, owner: TSymKind) =
proc addResult(c: PContext, n: PNode, t: PType, owner: TSymKind) =
if owner == skMacro or t != nil:
var s = newSym(skResult, getIdent(c.cache, "result"), getCurrOwner(c), info)
s.typ = t
incl(s.flags, sfUsed)
addParamOrResult(c, s, owner)
c.p.resultSym = s
proc addResultNode(c: PContext, n: PNode) =
if c.p.resultSym != nil: n.add newSymNode(c.p.resultSym)
if n.len > resultPos and n[resultPos] != nil:
if n[resultPos].sym.kind != skResult or n[resultPos].sym.owner != getCurrOwner(c):
localError(c.config, n.info, "incorrect result proc symbol")
c.p.resultSym = n[resultPos].sym
else:
var s = newSym(skResult, getIdent(c.cache, "result"), getCurrOwner(c), n.info)
s.typ = t
incl(s.flags, sfUsed)
c.p.resultSym = s
n.add newSymNode(c.p.resultSym)
addParamOrResult(c, c.p.resultSym, owner)
proc copyExcept(n: PNode, i: int): PNode =
result = copyNode(n)
@@ -1563,8 +1566,7 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
# XXX not good enough; see tnamedparamanonproc.nim
if gp.len == 0 or (gp.len == 1 and tfRetType in gp[0].typ.flags):
pushProcCon(c, s)
addResult(c, s.typ[0], n.info, skProc)
addResultNode(c, n)
addResult(c, n, s.typ[0], skProc)
s.ast[bodyPos] = hloBody(c, semProcBody(c, n[bodyPos]))
trackProc(c, s, s.ast[bodyPos])
popProcCon(c)
@@ -1606,8 +1608,7 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode {.nosinks.} =
pushOwner(c, s)
addParams(c, params, skProc)
pushProcCon(c, s)
addResult(c, n.typ[0], n.info, skProc)
addResultNode(c, n)
addResult(c, n, n.typ[0], skProc)
s.ast[bodyPos] = hloBody(c, semProcBody(c, n[bodyPos]))
trackProc(c, s, s.ast[bodyPos])
popProcCon(c)
@@ -1637,11 +1638,9 @@ proc activate(c: PContext, n: PNode) =
proc maybeAddResult(c: PContext, s: PSym, n: PNode) =
if s.kind == skMacro:
let resultType = sysTypeFromName(c.graph, n.info, "NimNode")
addResult(c, resultType, n.info, s.kind)
addResultNode(c, n)
addResult(c, n, resultType, s.kind)
elif s.typ[0] != nil and not isInlineIterator(s.typ):
addResult(c, s.typ[0], n.info, s.kind)
addResultNode(c, n)
addResult(c, n, s.typ[0], s.kind)
proc canonType(c: PContext, t: PType): PType =
if t.kind == tySequence:

View File

@@ -480,3 +480,20 @@ func expMin: float
func expMin: float {.aadMin.} = 1
echo expMin()
# issue #15389
block double_sem_for_procs:
macro aad(fns: varargs[typed]): typed =
result = newStmtList()
for fn in fns:
result.add fn
func exp(x: float): float {.aad.} =
var x1 = min(max(x, -708.4), 709.8)
if x1 > 0.0:
return x1 + 1.0
result = 10.0
discard exp(5.0)