next steps for closure consistency; fixes #176
This commit is contained in:
parent
39f399f424
commit
20b6dc3829
9 changed files with 495 additions and 9 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue