progress
This commit is contained in:
parent
87f6a9592c
commit
b17e1efc67
2 changed files with 34 additions and 18 deletions
|
|
@ -91,17 +91,23 @@ proc optimize(s: var Scope) =
|
||||||
filterNil(wasMoved)
|
filterNil(wasMoved)
|
||||||
filterNil(final)
|
filterNil(final)
|
||||||
|
|
||||||
proc toTree(s: var Scope; ret: PNode; onlyCareAboutVars = false): PNode =
|
type
|
||||||
|
ToTreeFlag = enum
|
||||||
|
onlyCareAboutVars,
|
||||||
|
producesValue
|
||||||
|
|
||||||
|
proc toTree(s: var Scope; ret: PNode; flags: set[ToTreeFlag]): PNode =
|
||||||
if not s.needsTry: optimize(s)
|
if not s.needsTry: optimize(s)
|
||||||
assert ret != nil
|
assert ret != nil
|
||||||
if s.vars.len == 0 and s.final.len == 0 and s.wasMoved.len == 0:
|
if s.vars.len == 0 and s.final.len == 0 and s.wasMoved.len == 0:
|
||||||
# trivial, nothing was done:
|
# trivial, nothing was done:
|
||||||
result = ret
|
result = ret
|
||||||
else:
|
else:
|
||||||
if isEmptyType(ret.typ):
|
let isExpr = producesValue in flags and not isEmptyType(ret.typ)
|
||||||
result = newNodeI(nkStmtList, ret.info)
|
if isExpr:
|
||||||
else:
|
|
||||||
result = newNodeIT(nkStmtListExpr, ret.info, ret.typ)
|
result = newNodeIT(nkStmtListExpr, ret.info, ret.typ)
|
||||||
|
else:
|
||||||
|
result = newNodeI(nkStmtList, ret.info)
|
||||||
|
|
||||||
if s.vars.len > 0:
|
if s.vars.len > 0:
|
||||||
let varSection = newNodeI(nkVarSection, ret.info)
|
let varSection = newNodeI(nkVarSection, ret.info)
|
||||||
|
|
@ -109,7 +115,7 @@ proc toTree(s: var Scope; ret: PNode; onlyCareAboutVars = false): PNode =
|
||||||
varSection.add newTree(nkIdentDefs, newSymNode(tmp), newNodeI(nkEmpty, ret.info),
|
varSection.add newTree(nkIdentDefs, newSymNode(tmp), newNodeI(nkEmpty, ret.info),
|
||||||
newNodeI(nkEmpty, ret.info))
|
newNodeI(nkEmpty, ret.info))
|
||||||
result.add varSection
|
result.add varSection
|
||||||
if onlyCareAboutVars:
|
if onlyCareAboutVars in flags:
|
||||||
result.add ret
|
result.add ret
|
||||||
s.vars.setLen 0
|
s.vars.setLen 0
|
||||||
elif s.needsTry:
|
elif s.needsTry:
|
||||||
|
|
@ -117,8 +123,11 @@ proc toTree(s: var Scope; ret: PNode; onlyCareAboutVars = false): PNode =
|
||||||
for m in s.wasMoved: finSection.add m
|
for m in s.wasMoved: finSection.add m
|
||||||
for i in countdown(s.final.high, 0): finSection.add s.final[i]
|
for i in countdown(s.final.high, 0): finSection.add s.final[i]
|
||||||
result.add newTryFinally(ret, finSection)
|
result.add newTryFinally(ret, finSection)
|
||||||
|
elif isExpr:
|
||||||
|
for m in s.wasMoved: result.add m
|
||||||
|
for i in countdown(s.final.high, 0): result.add s.final[i]
|
||||||
|
result.add ret
|
||||||
else:
|
else:
|
||||||
#assert isEmptyType(ret.typ)
|
|
||||||
result.add ret
|
result.add ret
|
||||||
for m in s.wasMoved: result.add m
|
for m in s.wasMoved: result.add m
|
||||||
for i in countdown(s.final.high, 0): result.add s.final[i]
|
for i in countdown(s.final.high, 0): result.add s.final[i]
|
||||||
|
|
@ -593,22 +602,25 @@ proc pVarTopLevel(v: PNode; c: var Con; s: var Scope; ri, res: PNode) =
|
||||||
elif ri.kind != nkEmpty:
|
elif ri.kind != nkEmpty:
|
||||||
res.add moveOrCopy(v, ri, c, s, isDecl = true)
|
res.add moveOrCopy(v, ri, c, s, isDecl = true)
|
||||||
|
|
||||||
template handleNestedTempl(n: untyped, processCall: untyped) =
|
template handleNestedTempl(n, processCall: untyped; alwaysStmt: bool) =
|
||||||
template maybeVoid(child, s): untyped =
|
template maybeVoid(child, s): untyped =
|
||||||
if isEmptyType(child.typ): p(child, c, s, normal)
|
if isEmptyType(child.typ): p(child, c, s, normal)
|
||||||
else: processCall(child, s)
|
else: processCall(child, s)
|
||||||
|
|
||||||
|
let treeFlags = if not isEmptyType(n.typ) and not alwaysStmt: {producesValue} else: {}
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkStmtList, nkStmtListExpr:
|
of nkStmtList, nkStmtListExpr:
|
||||||
# a statement list does not open a new scope
|
# a statement list does not open a new scope
|
||||||
if n.len == 0: return n
|
if n.len == 0: return n
|
||||||
result = copyNode(n)
|
result = copyNode(n)
|
||||||
|
if alwaysStmt: result.typ = nil
|
||||||
for i in 0..<n.len-1:
|
for i in 0..<n.len-1:
|
||||||
result.add p(n[i], c, s, normal)
|
result.add p(n[i], c, s, normal)
|
||||||
result.add maybeVoid(n[^1], s)
|
result.add maybeVoid(n[^1], s)
|
||||||
|
|
||||||
of nkCaseStmt:
|
of nkCaseStmt:
|
||||||
result = copyNode(n)
|
result = copyNode(n)
|
||||||
|
if alwaysStmt: result.typ = nil
|
||||||
result.add p(n[0], c, s, normal)
|
result.add p(n[0], c, s, normal)
|
||||||
for i in 1..<n.len:
|
for i in 1..<n.len:
|
||||||
let it = n[i]
|
let it = n[i]
|
||||||
|
|
@ -619,7 +631,7 @@ template handleNestedTempl(n: untyped, processCall: untyped) =
|
||||||
branch[j] = copyTree(it[j])
|
branch[j] = copyTree(it[j])
|
||||||
var ofScope = nestedScope(s)
|
var ofScope = nestedScope(s)
|
||||||
let ofResult = maybeVoid(it[^1], ofScope)
|
let ofResult = maybeVoid(it[^1], ofScope)
|
||||||
branch[^1] = toTree(ofScope, ofResult)
|
branch[^1] = toTree(ofScope, ofResult, treeFlags)
|
||||||
result.add branch
|
result.add branch
|
||||||
rememberParent(s, ofScope)
|
rememberParent(s, ofScope)
|
||||||
|
|
||||||
|
|
@ -629,20 +641,22 @@ template handleNestedTempl(n: untyped, processCall: untyped) =
|
||||||
result.add p(n[0], c, s, normal)
|
result.add p(n[0], c, s, normal)
|
||||||
var bodyScope = nestedScope(s)
|
var bodyScope = nestedScope(s)
|
||||||
let bodyResult = p(n[1], c, bodyScope, normal)
|
let bodyResult = p(n[1], c, bodyScope, normal)
|
||||||
result.add toTree(bodyScope, bodyResult)
|
result.add toTree(bodyScope, bodyResult, treeFlags)
|
||||||
rememberParent(s, bodyScope)
|
rememberParent(s, bodyScope)
|
||||||
dec c.inLoop
|
dec c.inLoop
|
||||||
|
|
||||||
of nkBlockStmt, nkBlockExpr:
|
of nkBlockStmt, nkBlockExpr:
|
||||||
result = copyNode(n)
|
result = copyNode(n)
|
||||||
|
if alwaysStmt: result.typ = nil
|
||||||
result.add n[0]
|
result.add n[0]
|
||||||
var bodyScope = nestedScope(s)
|
var bodyScope = nestedScope(s)
|
||||||
let bodyResult = processCall(n[1], bodyScope)
|
let bodyResult = processCall(n[1], bodyScope)
|
||||||
result.add toTree(bodyScope, bodyResult)
|
result.add toTree(bodyScope, bodyResult, treeFlags)
|
||||||
rememberParent(s, bodyScope)
|
rememberParent(s, bodyScope)
|
||||||
|
|
||||||
of nkIfStmt, nkIfExpr:
|
of nkIfStmt, nkIfExpr:
|
||||||
result = copyNode(n)
|
result = copyNode(n)
|
||||||
|
if alwaysStmt: result.typ = nil
|
||||||
for i in 0..<n.len:
|
for i in 0..<n.len:
|
||||||
let it = n[i]
|
let it = n[i]
|
||||||
var branch = shallowCopy(it)
|
var branch = shallowCopy(it)
|
||||||
|
|
@ -650,19 +664,20 @@ template handleNestedTempl(n: untyped, processCall: untyped) =
|
||||||
branchScope.parent = nil
|
branchScope.parent = nil
|
||||||
if it.kind in {nkElifBranch, nkElifExpr}:
|
if it.kind in {nkElifBranch, nkElifExpr}:
|
||||||
let cond = p(it[0], c, branchScope, normal)
|
let cond = p(it[0], c, branchScope, normal)
|
||||||
branch[0] = toTree(branchScope, cond, onlyCareAboutVars = true)
|
branch[0] = toTree(branchScope, cond, {producesValue, onlyCareAboutVars})
|
||||||
|
|
||||||
branchScope.parent = addr(s)
|
branchScope.parent = addr(s)
|
||||||
var branchResult = processCall(it[^1], branchScope)
|
var branchResult = processCall(it[^1], branchScope)
|
||||||
branch[^1] = toTree(branchScope, branchResult)
|
branch[^1] = toTree(branchScope, branchResult, treeFlags)
|
||||||
result.add branch
|
result.add branch
|
||||||
rememberParent(s, branchScope)
|
rememberParent(s, branchScope)
|
||||||
|
|
||||||
of nkTryStmt:
|
of nkTryStmt:
|
||||||
result = copyNode(n)
|
result = copyNode(n)
|
||||||
|
if alwaysStmt: result.typ = nil
|
||||||
var tryScope = nestedScope(s)
|
var tryScope = nestedScope(s)
|
||||||
var tryResult = maybeVoid(n[0], tryScope)
|
var tryResult = maybeVoid(n[0], tryScope)
|
||||||
result.add toTree(tryScope, tryResult)
|
result.add toTree(tryScope, tryResult, treeFlags)
|
||||||
rememberParent(s, tryScope)
|
rememberParent(s, tryScope)
|
||||||
|
|
||||||
for i in 1..<n.len:
|
for i in 1..<n.len:
|
||||||
|
|
@ -671,12 +686,13 @@ template handleNestedTempl(n: untyped, processCall: untyped) =
|
||||||
var branchScope = nestedScope(s)
|
var branchScope = nestedScope(s)
|
||||||
var branchResult = if it.kind == nkFinally: p(it[^1], c, branchScope, normal)
|
var branchResult = if it.kind == nkFinally: p(it[^1], c, branchScope, normal)
|
||||||
else: processCall(it[^1], branchScope)
|
else: processCall(it[^1], branchScope)
|
||||||
branch[^1] = toTree(branchScope, branchResult)
|
branch[^1] = toTree(branchScope, branchResult, treeFlags)
|
||||||
result.add branch
|
result.add branch
|
||||||
rememberParent(s, branchScope)
|
rememberParent(s, branchScope)
|
||||||
|
|
||||||
of nkWhen: # This should be a "when nimvm" node.
|
of nkWhen: # This should be a "when nimvm" node.
|
||||||
result = copyTree(n)
|
result = copyTree(n)
|
||||||
|
if alwaysStmt: result.typ = nil
|
||||||
result[1][0] = processCall(n[1][0], s)
|
result[1][0] = processCall(n[1][0], s)
|
||||||
else: assert(false)
|
else: assert(false)
|
||||||
|
|
||||||
|
|
@ -708,7 +724,7 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode): PNode =
|
||||||
if n.kind in {nkStmtList, nkStmtListExpr, nkBlockStmt, nkBlockExpr, nkIfStmt,
|
if n.kind in {nkStmtList, nkStmtListExpr, nkBlockStmt, nkBlockExpr, nkIfStmt,
|
||||||
nkIfExpr, nkCaseStmt, nkWhen, nkWhileStmt, nkTryStmt}:
|
nkIfExpr, nkCaseStmt, nkWhen, nkWhileStmt, nkTryStmt}:
|
||||||
template process(child, s): untyped = p(child, c, s, mode)
|
template process(child, s): untyped = p(child, c, s, mode)
|
||||||
handleNestedTempl(n, process)
|
handleNestedTempl(n, process, false)
|
||||||
elif mode == sinkArg:
|
elif mode == sinkArg:
|
||||||
if n.containsConstSeq:
|
if n.containsConstSeq:
|
||||||
# const sequences are not mutable and so we need to pass a copy to the
|
# const sequences are not mutable and so we need to pass a copy to the
|
||||||
|
|
@ -994,7 +1010,7 @@ proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope, isDecl = false): PNod
|
||||||
result = genSink(c, s, dest, p(ri, c, s, sinkArg), isDecl)
|
result = genSink(c, s, dest, p(ri, c, s, sinkArg), isDecl)
|
||||||
of nkStmtListExpr, nkBlockExpr, nkIfExpr, nkCaseStmt:
|
of nkStmtListExpr, nkBlockExpr, nkIfExpr, nkCaseStmt:
|
||||||
template process(child, s): untyped = moveOrCopy(dest, child, c, s, isDecl)
|
template process(child, s): untyped = moveOrCopy(dest, child, c, s, isDecl)
|
||||||
handleNestedTempl(ri, process)
|
handleNestedTempl(ri, process, true)
|
||||||
of nkRaiseStmt:
|
of nkRaiseStmt:
|
||||||
result = pRaiseStmt(ri, c, s)
|
result = pRaiseStmt(ri, c, s)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1071,7 +1087,7 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
|
||||||
scope.final.add genDestroy(c, params[i])
|
scope.final.add genDestroy(c, params[i])
|
||||||
#if optNimV2 in c.graph.config.globalOptions:
|
#if optNimV2 in c.graph.config.globalOptions:
|
||||||
# injectDefaultCalls(n, c)
|
# injectDefaultCalls(n, c)
|
||||||
result = toTree(scope, body)
|
result = toTree(scope, body, {})
|
||||||
dbg:
|
dbg:
|
||||||
echo ">---------transformed-to--------->"
|
echo ">---------transformed-to--------->"
|
||||||
echo renderTree(result, {renderIds})
|
echo renderTree(result, {renderIds})
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ proc myfunc2(x, y: int): tuple[a: MySeqNonCopyable, b:int, c:MySeqNonCopyable] =
|
||||||
var cc = newMySeq(y, 5.0)
|
var cc = newMySeq(y, 5.0)
|
||||||
(a: case x:
|
(a: case x:
|
||||||
of 1:
|
of 1:
|
||||||
let (z1, z2) = myfunc(x,y)
|
let (z1, z2) = myfunc(x, y)
|
||||||
z2
|
z2
|
||||||
elif x > 5: raise newException(ValueError, "new error")
|
elif x > 5: raise newException(ValueError, "new error")
|
||||||
else: newMySeq(x, 1.0),
|
else: newMySeq(x, 1.0),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue