next steps for closure consistency; fixes #176

This commit is contained in:
Araq 2012-07-25 21:59:31 +02:00
commit 20b6dc3829
9 changed files with 495 additions and 9 deletions

View file

@ -1092,6 +1092,14 @@ proc hasSonWith(n: PNode, kind: TNodeKind): bool =
return true
result = false
proc hasNilSon*(n: PNode): bool =
for i in countup(0, safeLen(n) - 1):
if n.sons[i] == nil:
return true
elif hasNilSon(n.sons[i]):
return true
result = false
proc containsNode*(n: PNode, kinds: TNodeKinds): bool =
if n == nil: return
case n.kind

View file

@ -131,7 +131,7 @@ type
localsToAccess: TIdNodeTable
TOuterContext {.final.} = object
fn: PSym
fn: PSym # may also be a module!
currentEnv: PEnv
capturedVars, processed: TIntSet
localsToEnv: TIdTable # PSym->PEnv mapping
@ -282,7 +282,7 @@ proc gatherVars(o: POuterContext, i: PInnerContext, n: PNode) =
if env == nil: InternalError(n.info, "no environment computed")
if o.currentEnv != env:
discard addDep(o.currentEnv, env, i.fn)
InternalError(n.info, "too complex enviroment handling required")
InternalError(n.info, "too complex environment handling required")
of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit: nil
else:
for k in countup(0, sonsLen(n) - 1):
@ -438,6 +438,8 @@ proc generateClosureCreation(o: POuterContext, scope: PEnv): PNode =
newSymNode(getClosureVar(o, e))))
proc transformOuterProc(o: POuterContext, n: PNode): PNode =
# XXX I with I knew where these 'nil' nodes come from: 'array[.. |X]'
if n == nil: return nil
case n.kind
of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit: nil
of nkSym:
@ -485,11 +487,12 @@ proc transformOuterProc(o: POuterContext, n: PNode): PNode =
let x = transformOuterProc(o, n.sons[i])
if x != nil: n.sons[i] = x
proc liftLambdas(fn: PSym, body: PNode): PNode =
proc liftLambdas*(fn: PSym, body: PNode): PNode =
if body.kind == nkEmpty:
# ignore forward declaration:
result = body
elif not containsNode(body, procDefs) and fn.typ.callConv != ccClosure:
elif (fn.typ == nil or fn.typ.callConv != ccClosure) and
not containsNode(body, procDefs):
# fast path: no inner procs, so no closure needed:
result = body
else:

View file

@ -87,7 +87,7 @@ proc AddInterfaceDeclAux(c: PContext, sym: PSym) =
# add to interface:
if c.module == nil: InternalError(sym.info, "AddInterfaceDeclAux")
StrTableAdd(c.module.tab, sym)
if getCurrOwner().kind == skModule: incl(sym.flags, sfGlobal)
#if getCurrOwner().kind == skModule: incl(sym.flags, sfGlobal)
proc addInterfaceDeclAt*(c: PContext, sym: PSym, at: Natural) =
addDeclAt(c, sym, at)

View file

@ -108,7 +108,7 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
incl(c.p.owner.flags, sfSideEffect)
elif s.kind == skParam and s.typ.kind == tyExpr:
return s.typ.n
elif s.owner != c.p.owner and s.owner.kind != skModule and
elif s.owner != c.p.owner and
c.p.owner.typ != nil and not IsGenericRoutine(s.owner):
c.p.owner.typ.callConv = ccClosure
if illegalCapture(s) or c.p.next.owner != s.owner:

View file

@ -827,7 +827,6 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
of nkStmtListType: result = semStmtListType(c, n, prev)
of nkBlockType: result = semBlockType(c, n, prev)
else: GlobalError(n.info, errTypeExpected)
#internalError(n.info, 'semTypeNode(' +{&} nodeKindToStr[n.kind] +{&} ')');
proc setMagicType(m: PSym, kind: TTypeKind, size: int) =
m.typ.kind = kind