first implementation of new lambda lifting

This commit is contained in:
Araq 2012-06-15 23:18:52 +02:00
commit 15dad22a0a
5 changed files with 411 additions and 215 deletions

View file

@ -19,7 +19,8 @@
import
intsets, strutils, lists, options, ast, astalgo, trees, treetab, msgs, os,
idents, renderer, types, passes, semfold, magicsys, cgmeth, rodread
idents, renderer, types, passes, semfold, magicsys, cgmeth, rodread,
lambdalifting
const
genPrefix* = ":tmp" # prefix for generated names
@ -193,7 +194,7 @@ proc transformSym(c: PTransf, n: PNode): PTransNode =
proc transformVarSection(c: PTransf, v: PNode): PTransNode =
result = newTransNode(v)
for i in countup(0, sonsLen(v)-1):
for i in countup(0, sonsLen(v)-1):
var it = v.sons[i]
if it.kind == nkCommentStmt:
result[i] = PTransNode(it)
@ -349,13 +350,6 @@ proc transformYield(c: PTransf, n: PNode): PTransNode =
# we need to introduce new local variables:
add(result, introduceNewLocalVars(c, c.transCon.forLoopBody.pnode))
proc addVar(father, v: PNode) =
var vpart = newNodeI(nkIdentDefs, v.info)
addSon(vpart, v)
addSon(vpart, ast.emptyNode)
addSon(vpart, ast.emptyNode)
addSon(father, vpart)
proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode =
result = transformSons(c, n)
var n = result.pnode
@ -377,7 +371,18 @@ proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PTransNode =
# addr ( deref ( x )) --> x
result = PTransNode(n.sons[0].sons[0])
include lambdalifting
proc generateThunk(c: PTransf, prc: PNode, dest: PType): PNode =
## Converts 'prc' into '(thunk, nil)' so that it's compatible with
## a closure.
# we cannot generate a proper thunk here for GC-safety reasons (see internal
# documentation):
result = newNodeIT(nkClosure, prc.info, dest)
var conv = newNodeIT(nkHiddenStdConv, prc.info, dest)
conv.add(emptyNode)
conv.add(prc)
result.add(conv)
result.add(newNodeIT(nkNilLit, prc.info, getSysType(tyNil)))
proc transformConv(c: PTransf, n: PNode): PTransNode =
# numeric types need range checks:
@ -638,7 +643,14 @@ proc transform(c: PTransf, n: PNode): PTransNode =
# nothing to be done for leaves:
result = PTransNode(n)
of nkBracketExpr: result = transformArrayAccess(c, n)
of procDefs, nkMacroDef:
of procDefs:
if n.sons[genericParamsPos].kind == nkEmpty:
var s = n.sons[namePos].sym
n.sons[bodyPos] = PNode(transform(c, s.getBody))
n.sons[bodyPos] = liftLambdas(n)
if n.kind == nkMethodDef: methodDef(s, false)
result = PTransNode(n)
of nkMacroDef:
# XXX no proper closure support yet:
if n.sons[genericParamsPos].kind == nkEmpty:
var s = n.sons[namePos].sym
@ -737,10 +749,9 @@ proc transfPass(): TPass =
result.close = processTransf # we need to process generics too!
proc transform*(module: PSym, n: PNode): PNode =
if nfTransf in n.flags:
if nfTransf in n.flags:
result = n
else:
var c = openTransf(module, "")
result = processTransf(c, n)
incl(result.flags, nfTransf)