Cosmetics

This commit is contained in:
Yuriy Glukhov 2018-05-08 12:32:55 +03:00
commit d99c82bc3b
2 changed files with 77 additions and 164 deletions

View file

@ -131,9 +131,8 @@
# break :stateLoop # break :stateLoop
import import
intsets, strutils, options, ast, astalgo, trees, treetab, msgs, os, options, intsets, strutils, options, ast, astalgo, trees, treetab, msgs, idents,
idents, renderer, types, magicsys, rodread, lowerings, tables, sequtils, renderer, types, magicsys, rodread, lowerings, lambdalifting
lambdalifting
type type
Ctx = object Ctx = object
@ -164,9 +163,7 @@ proc newStateAccess(ctx: var Ctx): PNode =
proc newStateAssgn(ctx: var Ctx, toValue: PNode): PNode = proc newStateAssgn(ctx: var Ctx, toValue: PNode): PNode =
# Creates state assignment: # Creates state assignment:
# :state = toValue # :state = toValue
result = newNode(nkAsgn) newTree(nkAsgn, ctx.newStateAccess(), toValue)
result.add(ctx.newStateAccess())
result.add(toValue)
proc newStateAssgn(ctx: var Ctx, stateNo: int = -2): PNode = proc newStateAssgn(ctx: var Ctx, stateNo: int = -2): PNode =
# Creates state assignment: # Creates state assignment:
@ -300,22 +297,16 @@ proc transformBreaksInBlock(ctx: var Ctx, n: PNode, label, after: PNode): PNode
proc newNullifyCurExc(ctx: var Ctx): PNode = proc newNullifyCurExc(ctx: var Ctx): PNode =
# :curEcx = nil # :curEcx = nil
result = newNode(nkAsgn)
let curExc = ctx.newCurExcAccess() let curExc = ctx.newCurExcAccess()
result.add(curExc)
let nilnode = newNode(nkNilLit) let nilnode = newNode(nkNilLit)
nilnode.typ = curExc.typ nilnode.typ = curExc.typ
result.add(nilnode) result = newTree(nkAsgn, curExc, nilnode)
proc newOr(a, b: PNode): PNode = proc newOr(a, b: PNode): PNode {.inline.} =
result = newNode(nkCall) result = newTree(nkCall, newSymNode(getSysMagic("or", mOr)), a, b)
result.add(newSymNode(getSysMagic("or", mOr)))
result.add(a)
result.add(b)
result.typ = getSysType(tyBool) result.typ = getSysType(tyBool)
proc collectExceptState(ctx: var Ctx, n: PNode): PNode = proc collectExceptState(ctx: var Ctx, n: PNode): PNode {.inline.} =
var ifStmt = newNode(nkIfStmt) var ifStmt = newNode(nkIfStmt)
for c in n: for c in n:
if c.kind == nkExceptBranch: if c.kind == nkExceptBranch:
@ -349,9 +340,7 @@ proc collectExceptState(ctx: var Ctx, n: PNode): PNode =
ifStmt.add(ifBranch) ifStmt.add(ifBranch)
if ifStmt.len != 0: if ifStmt.len != 0:
result = newNode(nkStmtList) result = newTree(nkStmtList, ctx.newNullifyCurExc(), ifStmt)
result.add(ctx.newNullifyCurExc())
result.add(ifStmt)
else: else:
result = emptyNode result = emptyNode
@ -362,21 +351,17 @@ proc addElseToExcept(ctx: var Ctx, n: PNode) =
let branchBody = newNode(nkStmtList) let branchBody = newNode(nkStmtList)
block: # :unrollFinally = true block: # :unrollFinally = true
let asgn = newNode(nkAsgn) branchBody.add(newTree(nkAsgn,
asgn.add(ctx.newUnrollFinallyAccess()) ctx.newUnrollFinallyAccess(),
asgn.add(newIntTypeNode(nkIntLit, 1, getSysType(tyBool))) newIntTypeNode(nkIntLit, 1, getSysType(tyBool))))
branchBody.add(asgn)
block: # :curExc = getCurrentException() block: # :curExc = getCurrentException()
let asgn = newNode(nkAsgn) branchBody.add(newTree(nkAsgn,
asgn.add(ctx.newCurExcAccess) ctx.newCurExcAccess(),
asgn.add(callCodegenProc("getCurrentException", emptyNode)) callCodegenProc("getCurrentException", emptyNode)))
branchBody.add(asgn)
block: # goto nearestFinally block: # goto nearestFinally
let goto = newNode(nkGotoState) branchBody.add(newTree(nkGotoState, newIntLit(ctx.nearestFinally)))
goto.add(newIntLit(ctx.nearestFinally))
branchBody.add(goto)
elseBranch.add(branchBody) elseBranch.add(branchBody)
n[1].add(elseBranch) n[1].add(elseBranch)
@ -421,9 +406,7 @@ proc exprToStmtList(n: PNode): tuple[s, res: PNode] =
result.res = lastSon result.res = lastSon
proc newEnvVarAsgn(ctx: Ctx, s: PSym, v: PNode): PNode = proc newEnvVarAsgn(ctx: Ctx, s: PSym, v: PNode): PNode =
result = newNode(nkFastAsgn) newTree(nkFastAsgn, ctx.newEnvVarAccess(s), v)
result.add(ctx.newEnvVarAccess(s))
result.add(v)
proc addExprAssgn(ctx: Ctx, output, input: PNode, sym: PSym) = proc addExprAssgn(ctx: Ctx, output, input: PNode, sym: PSym) =
if input.kind == nkStmtListExpr: if input.kind == nkStmtListExpr:
@ -438,9 +421,7 @@ proc convertExprBodyToAsgn(ctx: Ctx, exprBody: PNode, res: PSym): PNode =
ctx.addExprAssgn(result, exprBody, res) ctx.addExprAssgn(result, exprBody, res)
proc newNotCall(e: PNode): PNode = proc newNotCall(e: PNode): PNode =
result = newNode(nkCall) result = newTree(nkCall, newSymNode(getSysMagic("not", mNot)), e)
result.add(newSymNode(getSysMagic("not", mNot)))
result.add(e)
result.typ = getSysType(tyBool) result.typ = getSysType(tyBool)
proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode = proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
@ -751,19 +732,11 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
needsSplit = true needsSplit = true
if condNeedsSplit: if condNeedsSplit:
let newBody = newNode(nkStmtList)
let (st, ex) = exprToStmtList(n[0]) let (st, ex) = exprToStmtList(n[0])
newBody.add(st) let brk = newTree(nkBreakStmt, emptyNode)
let check = newNode(nkIfStmt) let branch = newTree(nkElifBranch, newNotCall(ex), brk)
let branch = newNode(nkElifBranch) let check = newTree(nkIfStmt, branch)
branch.add(newNotCall(ex)) let newBody = newTree(nkStmtList, st, check, n[1])
let brk = newNode(nkBreakStmt)
brk.add(emptyNode)
branch.add(brk)
check.add(branch)
newBody.add(check)
newBody.add(n[1])
n[0] = newSymNode(getSysSym("true")) n[0] = newSymNode(getSysSym("true"))
n[1] = newBody n[1] = newBody
@ -778,44 +751,26 @@ proc newEndFinallyNode(ctx: var Ctx): PNode =
# return :tmpResult # return :tmpResult
# else: # else:
# raise # raise
result = newNode(nkIfStmt)
let elifBranch = newNode(nkElifBranch)
elifBranch.add(ctx.newUnrollFinallyAccess())
result.add(elifBranch)
let ifBody = newNode(nkIfStmt)
let branch = newNode(nkElifBranch)
let cmp = newNode(nkCall)
cmp.add(getSysMagic("==", mEqRef).newSymNode)
let curExc = ctx.newCurExcAccess() let curExc = ctx.newCurExcAccess()
let nilnode = newNode(nkNilLit) let nilnode = newNode(nkNilLit)
nilnode.typ = curExc.typ nilnode.typ = curExc.typ
cmp.add(curExc) let cmp = newTree(nkCall, getSysMagic("==", mEqRef).newSymNode, curExc, nilnode)
cmp.add(nilnode)
cmp.typ = getSysType(tyBool) cmp.typ = getSysType(tyBool)
branch.add(cmp)
let retStmt = newNode(nkReturnStmt) let asgn = newTree(nkFastAsgn,
let asgn = newNode(nkFastAsgn) newSymNode(getClosureIterResult(ctx.fn)),
addSon(asgn, newSymNode(getClosureIterResult(ctx.fn))) ctx.newTmpResultAccess())
addSon(asgn, ctx.newTmpResultAccess())
retStmt.add(asgn)
branch.add(retStmt)
let elseBranch = newNode(nkElse) let retStmt = newTree(nkReturnStmt, asgn)
let raiseStmt = newNode(nkRaiseStmt) let branch = newTree(nkElifBranch, cmp, retStmt)
# The C++ backend requires `getCurrentException` here. # The C++ backend requires `getCurrentException` here.
raiseStmt.add(callCodegenProc("getCurrentException", emptyNode)) let raiseStmt = newTree(nkRaiseStmt, callCodegenProc("getCurrentException", emptyNode))
elseBranch.add(raiseStmt) let elseBranch = newTree(nkElse, raiseStmt)
ifBody.add(branch) let ifBody = newTree(nkIfStmt, branch, elseBranch)
ifBody.add(elseBranch) let elifBranch = newTree(nkElifBranch, ctx.newUnrollFinallyAccess(), ifBody)
result = newTree(nkIfStmt, elifBranch)
elifBranch.add(ifBody)
proc transformReturnsInTry(ctx: var Ctx, n: PNode): PNode = proc transformReturnsInTry(ctx: var Ctx, n: PNode): PNode =
result = n result = n
@ -950,8 +905,7 @@ proc transformClosureIteratorBody(ctx: var Ctx, n: PNode, gotoOut: PNode): PNode
result = newNode(nkGotoState) result = newNode(nkGotoState)
var tryBody = toStmtList(n[0]) var tryBody = toStmtList(n[0])
var exceptBody = ctx.collectExceptState(n) var exceptBody = ctx.collectExceptState(n)
var finallyBody = newNode(nkStmtList) var finallyBody = newTree(nkStmtList, getFinallyNode(n))
finallyBody.add(getFinallyNode(n))
finallyBody = ctx.transformReturnsInTry(finallyBody) finallyBody = ctx.transformReturnsInTry(finallyBody)
finallyBody.add(ctx.newEndFinallyNode()) finallyBody.add(ctx.newEndFinallyNode())
@ -1125,15 +1079,13 @@ proc newArrayType(n: int, t: PType, owner: PSym): PType =
result = newType(tyArray, owner) result = newType(tyArray, owner)
let rng = newType(tyRange, owner) let rng = newType(tyRange, owner)
rng.n = newNode(nkRange) rng.n = newTree(nkRange, newIntLit(0), newIntLit(n))
rng.n.add(newIntLit(0))
rng.n.add(newIntLit(n))
rng.rawAddSon(t) rng.rawAddSon(t)
result.rawAddSon(rng) result.rawAddSon(rng)
result.rawAddSon(t) result.rawAddSon(t)
proc createExceptionTable(ctx: var Ctx): PNode = proc createExceptionTable(ctx: var Ctx): PNode {.inline.} =
result = newNode(nkBracket) result = newNode(nkBracket)
result.typ = newArrayType(ctx.exceptionTable.len, getSysType(tyInt16), ctx.fn) result.typ = newArrayType(ctx.exceptionTable.len, getSysType(tyInt16), ctx.fn)
@ -1157,9 +1109,9 @@ proc newCatchBody(ctx: var Ctx): PNode {.inline.} =
block: block:
# exceptionTable[:state] # exceptionTable[:state]
let getNextState = newNode(nkBracketExpr) let getNextState = newTree(nkBracketExpr,
getNextState.add(ctx.createExceptionTable) ctx.createExceptionTable(),
getNextState.add(ctx.newStateAccess()) ctx.newStateAccess())
getNextState.typ = getSysType(tyInt) getNextState.typ = getSysType(tyInt)
# :state = exceptionTable[:state] # :state = exceptionTable[:state]
@ -1167,96 +1119,68 @@ proc newCatchBody(ctx: var Ctx): PNode {.inline.} =
# if :state == 0: raise # if :state == 0: raise
block: block:
let ifStmt = newNode(nkIfStmt) let cond = newTree(nkCall,
let ifBranch = newNode(nkElifBranch) getSysMagic("==", mEqI).newSymNode(),
let cond = newNode(nkCall) ctx.newStateAccess(),
cond.add(getSysMagic("==", mEqI).newSymNode) newIntTypeNode(nkIntLit, 0, getSysType(tyInt)))
cond.add(ctx.newStateAccess())
cond.add(newIntTypeNode(nkIntLit, 0, getSysType(tyInt)))
cond.typ = getSysType(tyBool) cond.typ = getSysType(tyBool)
ifBranch.add(cond)
let raiseStmt = newNode(nkRaiseStmt) let raiseStmt = newTree(nkRaiseStmt, emptyNode)
raiseStmt.add(emptyNode) let ifBranch = newTree(nkElifBranch, cond, raiseStmt)
let ifStmt = newTree(nkIfStmt, ifBranch)
ifBranch.add(raiseStmt)
ifStmt.add(ifBranch)
result.add(ifStmt) result.add(ifStmt)
# :unrollFinally = :state > 0 # :unrollFinally = :state > 0
block: block:
let asgn = newNode(nkAsgn) let cond = newTree(nkCall,
asgn.add(ctx.newUnrollFinallyAccess()) getSysMagic("<", mLtI).newSymNode,
newIntTypeNode(nkIntLit, 0, getSysType(tyInt)),
let cond = newNode(nkCall) ctx.newStateAccess())
cond.add(getSysMagic("<", mLtI).newSymNode)
cond.add(newIntTypeNode(nkIntLit, 0, getSysType(tyInt)))
cond.add(ctx.newStateAccess())
cond.typ = getSysType(tyBool) cond.typ = getSysType(tyBool)
asgn.add(cond)
let asgn = newTree(nkAsgn, ctx.newUnrollFinallyAccess(), cond)
result.add(asgn) result.add(asgn)
# if :state < 0: :state = -:state # if :state < 0: :state = -:state
block: block:
let ifStmt = newNode(nkIfStmt) let cond = newTree(nkCall,
let ifBranch = newNode(nkElifBranch) getSysMagic("<", mLtI).newSymNode,
let cond = newNode(nkCall) ctx.newStateAccess(),
cond.add(getSysMagic("<", mLtI).newSymNode) newIntTypeNode(nkIntLit, 0, getSysType(tyInt)))
cond.add(ctx.newStateAccess())
cond.add(newIntTypeNode(nkIntLit, 0, getSysType(tyInt)))
cond.typ = getSysType(tyBool) cond.typ = getSysType(tyBool)
ifBranch.add(cond)
let negateState = newNode(nkCall) let negateState = newTree(nkCall,
negateState.add(getSysMagic("-", mUnaryMinusI).newSymNode) getSysMagic("-", mUnaryMinusI).newSymNode,
negateState.add(ctx.newStateAccess()) ctx.newStateAccess())
negateState.typ = getSysType(tyInt) negateState.typ = getSysType(tyInt)
ifBranch.add(ctx.newStateAssgn(negateState)) let ifBranch = newTree(nkElifBranch, cond, ctx.newStateAssgn(negateState))
ifStmt.add(ifBranch) let ifStmt = newTree(nkIfStmt, ifBranch)
result.add(ifStmt) result.add(ifStmt)
# :curExc = getCurrentException() # :curExc = getCurrentException()
block: block:
let getCurExc = callCodegenProc("getCurrentException", emptyNode) result.add(newTree(nkAsgn,
let asgn = newNode(nkAsgn) ctx.newCurExcAccess(),
asgn.add(ctx.newCurExcAccess()) callCodegenProc("getCurrentException", emptyNode)))
asgn.add(getCurExc)
result.add(asgn)
proc wrapIntoTryExcept(ctx: var Ctx, n: PNode): PNode = proc wrapIntoTryExcept(ctx: var Ctx, n: PNode): PNode {.inline.} =
result = newNode(nkTryStmt) let setupExc = newTree(nkCall,
newSymNode(getCompilerProc("closureIterSetupExc")),
ctx.newCurExcAccess())
let tryBody = newNode(nkStmtList) let tryBody = newTree(nkStmtList, setupExc, n)
let exceptBranch = newTree(nkExceptBranch, ctx.newCatchBody())
let setupExc = newNode(nkCall) result = newTree(nkTryStmt, tryBody, exceptBranch)
setupExc.add(newSymNode(getCompilerProc("closureIterSetupExc")))
tryBody.add(setupExc)
tryBody.add(n)
result.add(tryBody)
let catchNode = newNode(nkExceptBranch)
result.add(catchNode)
let catchBody = newNode(nkStmtList)
catchBody.add(ctx.newCatchBody())
catchNode.add(catchBody)
setupExc.add(ctx.newCurExcAccess())
proc wrapIntoStateLoop(ctx: var Ctx, n: PNode): PNode = proc wrapIntoStateLoop(ctx: var Ctx, n: PNode): PNode =
# while true: # while true:
# block :stateLoop: # block :stateLoop:
# gotoState :state # gotoState :state
# body # Might get wrapped in try-except # body # Might get wrapped in try-except
result = newNode(nkWhileStmt)
result.add(newSymNode(getSysSym("true")))
let loopBody = newNodeI(nkStmtList, n.info) let loopBody = newNodeI(nkStmtList, n.info)
result.add(loopBody) result = newTree(nkWhileStmt, newSymNode(getSysSym("true")), loopBody)
if not ctx.stateVarSym.isNil: if not ctx.stateVarSym.isNil:
let varSect = newNodeI(nkVarSection, n.info) let varSect = newNodeI(nkVarSection, n.info)
@ -1269,26 +1193,19 @@ proc wrapIntoStateLoop(ctx: var Ctx, n: PNode): PNode =
let blockStmt = newNodeI(nkBlockStmt, n.info) let blockStmt = newNodeI(nkBlockStmt, n.info)
blockStmt.add(newSymNode(ctx.stateLoopLabel)) blockStmt.add(newSymNode(ctx.stateLoopLabel))
var blockBody = newNodeI(nkStmtList, n.info)
let gs = newNodeI(nkGotoState, n.info) let gs = newNodeI(nkGotoState, n.info)
gs.add(ctx.newStateAccess()) gs.add(ctx.newStateAccess())
gs.add(newIntLit(ctx.states.len - 1)) gs.add(newIntLit(ctx.states.len - 1))
blockBody.add(gs) var blockBody = newTree(nkStmtList, gs, n)
blockBody.add(n)
if ctx.hasExceptions: if ctx.hasExceptions:
blockBody = ctx.wrapIntoTryExcept(blockBody) blockBody = ctx.wrapIntoTryExcept(blockBody)
blockStmt.add(blockBody) blockStmt.add(blockBody)
loopBody.add(blockStmt) loopBody.add(blockStmt)
proc deleteEmptyStates(ctx: var Ctx) = proc deleteEmptyStates(ctx: var Ctx) =
let goOut = newNode(nkGotoState) let goOut = newTree(nkGotoState, newIntLit(-1))
goOut.add(newIntLit(-1))
ctx.exitStateIdx = ctx.newState(goOut, nil) ctx.exitStateIdx = ctx.newState(goOut, nil)
# Apply new state indexes and mark unused states with -1 # Apply new state indexes and mark unused states with -1
@ -1332,14 +1249,11 @@ proc transformClosureIterator*(fn: PSym, n: PNode): PNode =
ctx.stateVarSym = newSym(skVar, getIdent(":state"), fn, fn.info) ctx.stateVarSym = newSym(skVar, getIdent(":state"), fn, fn.info)
ctx.stateVarSym.typ = createClosureIterStateType(fn) ctx.stateVarSym.typ = createClosureIterStateType(fn)
ctx.states = @[]
ctx.stateLoopLabel = newSym(skLabel, getIdent(":stateLoop"), fn, fn.info) ctx.stateLoopLabel = newSym(skLabel, getIdent(":stateLoop"), fn, fn.info)
ctx.exceptionTable = @[]
let n = n.toStmtList let n = n.toStmtList
discard ctx.newState(n, nil) discard ctx.newState(n, nil)
let gotoOut = newNode(nkGotoState) let gotoOut = newTree(nkGotoState, newIntLit(-1))
gotoOut.add(newIntLit(-1))
# Splitting transformation # Splitting transformation
discard ctx.transformClosureIteratorBody(n, gotoOut) discard ctx.transformClosureIteratorBody(n, gotoOut)
@ -1349,8 +1263,7 @@ proc transformClosureIterator*(fn: PSym, n: PNode): PNode =
# Make new body by concating the list of states # Make new body by concating the list of states
result = newNode(nkStmtList) result = newNode(nkStmtList)
for i, s in ctx.states: for s in ctx.states:
# result.add(s)
let body = s[1] let body = s[1]
s.sons.del(1) s.sons.del(1)
result.add(s) result.add(s)

View file

@ -10,8 +10,8 @@
# This file implements lambda lifting for the transformator. # This file implements lambda lifting for the transformator.
import import
intsets, strutils, options, ast, astalgo, trees, treetab, msgs, os, options, intsets, strutils, options, ast, astalgo, trees, treetab, msgs,
idents, renderer, types, magicsys, rodread, lowerings, tables, sequtils idents, renderer, types, magicsys, rodread, lowerings, tables
discard """ discard """
The basic approach is that captured vars need to be put on the heap and The basic approach is that captured vars need to be put on the heap and