* allow result symbol reuse * try different approach * Revert "try different approach" This reverts commit abcfb6b75983c2f798cc887342ff1a9ff10c0324.
This commit is contained in:
parent
fe3211fbcf
commit
f21a49b2c4
3 changed files with 44 additions and 24 deletions
|
|
@ -1754,17 +1754,21 @@ proc semReturn(c: PContext, n: PNode): PNode =
|
||||||
if c.p.owner.kind in {skConverter, skMethod, skProc, skFunc, skMacro} or
|
if c.p.owner.kind in {skConverter, skMethod, skProc, skFunc, skMacro} or
|
||||||
(not c.p.owner.typ.isNil and isClosureIterator(c.p.owner.typ)):
|
(not c.p.owner.typ.isNil and isClosureIterator(c.p.owner.typ)):
|
||||||
if n[0].kind != nkEmpty:
|
if n[0].kind != nkEmpty:
|
||||||
# transform ``return expr`` to ``result = expr; return``
|
if n[0].kind == nkAsgn and n[0][0].kind == nkSym and c.p.resultSym == n[0][0].sym:
|
||||||
if c.p.resultSym != nil:
|
discard "return is already transformed"
|
||||||
|
elif c.p.resultSym != nil:
|
||||||
|
# transform ``return expr`` to ``result = expr; return``
|
||||||
var a = newNodeI(nkAsgn, n[0].info)
|
var a = newNodeI(nkAsgn, n[0].info)
|
||||||
a.add newSymNode(c.p.resultSym)
|
a.add newSymNode(c.p.resultSym)
|
||||||
a.add n[0]
|
a.add n[0]
|
||||||
n[0] = semAsgn(c, a)
|
n[0] = a
|
||||||
# optimize away ``result = result``:
|
else:
|
||||||
if n[0][1].kind == nkSym and n[0][1].sym == c.p.resultSym:
|
|
||||||
n[0] = c.graph.emptyNode
|
|
||||||
else:
|
|
||||||
localError(c.config, n.info, errNoReturnTypeDeclared)
|
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:
|
else:
|
||||||
localError(c.config, n.info, "'return' not allowed here")
|
localError(c.config, n.info, "'return' not allowed here")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1430,16 +1430,19 @@ proc semBorrow(c: PContext, n: PNode, s: PSym) =
|
||||||
else:
|
else:
|
||||||
localError(c.config, n.info, errNoSymbolToBorrowFromFound)
|
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:
|
if owner == skMacro or t != nil:
|
||||||
var s = newSym(skResult, getIdent(c.cache, "result"), getCurrOwner(c), info)
|
if n.len > resultPos and n[resultPos] != nil:
|
||||||
s.typ = t
|
if n[resultPos].sym.kind != skResult or n[resultPos].sym.owner != getCurrOwner(c):
|
||||||
incl(s.flags, sfUsed)
|
localError(c.config, n.info, "incorrect result proc symbol")
|
||||||
addParamOrResult(c, s, owner)
|
c.p.resultSym = n[resultPos].sym
|
||||||
c.p.resultSym = s
|
else:
|
||||||
|
var s = newSym(skResult, getIdent(c.cache, "result"), getCurrOwner(c), n.info)
|
||||||
proc addResultNode(c: PContext, n: PNode) =
|
s.typ = t
|
||||||
if c.p.resultSym != nil: n.add newSymNode(c.p.resultSym)
|
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 =
|
proc copyExcept(n: PNode, i: int): PNode =
|
||||||
result = copyNode(n)
|
result = copyNode(n)
|
||||||
|
|
@ -1563,8 +1566,7 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
# XXX not good enough; see tnamedparamanonproc.nim
|
# XXX not good enough; see tnamedparamanonproc.nim
|
||||||
if gp.len == 0 or (gp.len == 1 and tfRetType in gp[0].typ.flags):
|
if gp.len == 0 or (gp.len == 1 and tfRetType in gp[0].typ.flags):
|
||||||
pushProcCon(c, s)
|
pushProcCon(c, s)
|
||||||
addResult(c, s.typ[0], n.info, skProc)
|
addResult(c, n, s.typ[0], skProc)
|
||||||
addResultNode(c, n)
|
|
||||||
s.ast[bodyPos] = hloBody(c, semProcBody(c, n[bodyPos]))
|
s.ast[bodyPos] = hloBody(c, semProcBody(c, n[bodyPos]))
|
||||||
trackProc(c, s, s.ast[bodyPos])
|
trackProc(c, s, s.ast[bodyPos])
|
||||||
popProcCon(c)
|
popProcCon(c)
|
||||||
|
|
@ -1606,8 +1608,7 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode {.nosinks.} =
|
||||||
pushOwner(c, s)
|
pushOwner(c, s)
|
||||||
addParams(c, params, skProc)
|
addParams(c, params, skProc)
|
||||||
pushProcCon(c, s)
|
pushProcCon(c, s)
|
||||||
addResult(c, n.typ[0], n.info, skProc)
|
addResult(c, n, n.typ[0], skProc)
|
||||||
addResultNode(c, n)
|
|
||||||
s.ast[bodyPos] = hloBody(c, semProcBody(c, n[bodyPos]))
|
s.ast[bodyPos] = hloBody(c, semProcBody(c, n[bodyPos]))
|
||||||
trackProc(c, s, s.ast[bodyPos])
|
trackProc(c, s, s.ast[bodyPos])
|
||||||
popProcCon(c)
|
popProcCon(c)
|
||||||
|
|
@ -1637,11 +1638,9 @@ proc activate(c: PContext, n: PNode) =
|
||||||
proc maybeAddResult(c: PContext, s: PSym, n: PNode) =
|
proc maybeAddResult(c: PContext, s: PSym, n: PNode) =
|
||||||
if s.kind == skMacro:
|
if s.kind == skMacro:
|
||||||
let resultType = sysTypeFromName(c.graph, n.info, "NimNode")
|
let resultType = sysTypeFromName(c.graph, n.info, "NimNode")
|
||||||
addResult(c, resultType, n.info, s.kind)
|
addResult(c, n, resultType, s.kind)
|
||||||
addResultNode(c, n)
|
|
||||||
elif s.typ[0] != nil and not isInlineIterator(s.typ):
|
elif s.typ[0] != nil and not isInlineIterator(s.typ):
|
||||||
addResult(c, s.typ[0], n.info, s.kind)
|
addResult(c, n, s.typ[0], s.kind)
|
||||||
addResultNode(c, n)
|
|
||||||
|
|
||||||
proc canonType(c: PContext, t: PType): PType =
|
proc canonType(c: PContext, t: PType): PType =
|
||||||
if t.kind == tySequence:
|
if t.kind == tySequence:
|
||||||
|
|
|
||||||
|
|
@ -480,3 +480,20 @@ func expMin: float
|
||||||
func expMin: float {.aadMin.} = 1
|
func expMin: float {.aadMin.} = 1
|
||||||
|
|
||||||
echo expMin()
|
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)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue