first steps to working closures
This commit is contained in:
parent
232ab71f20
commit
5f527769ee
3 changed files with 24 additions and 19 deletions
|
|
@ -14,6 +14,20 @@ const
|
||||||
declarativeDefs = {nkProcDef, nkMethodDef, nkIteratorDef, nkConverterDef}
|
declarativeDefs = {nkProcDef, nkMethodDef, nkIteratorDef, nkConverterDef}
|
||||||
procDefs = nkLambdaKinds + declarativeDefs
|
procDefs = nkLambdaKinds + declarativeDefs
|
||||||
|
|
||||||
|
type
|
||||||
|
TCapture = seq[PSym]
|
||||||
|
|
||||||
|
TLLShared {.final.} = object
|
||||||
|
transformedInnerProcs: TIntSet
|
||||||
|
c: PTransf
|
||||||
|
|
||||||
|
TLLContext {.final.} = object
|
||||||
|
outerProc, innerProc: PSym
|
||||||
|
mapping: TIdNodeTable # mapping from symbols to nodes
|
||||||
|
shared: ref TLLShared
|
||||||
|
|
||||||
|
PLLContext = ref TLLContext
|
||||||
|
|
||||||
proc indirectAccess(a, b: PSym, info: TLineInfo): PNode =
|
proc indirectAccess(a, b: PSym, info: TLineInfo): PNode =
|
||||||
# returns a[].b as a node
|
# returns a[].b as a node
|
||||||
let x = newSymNode(a)
|
let x = newSymNode(a)
|
||||||
|
|
@ -27,9 +41,6 @@ proc indirectAccess(a, b: PSym, info: TLineInfo): PNode =
|
||||||
addSon(result, newSymNode(field))
|
addSon(result, newSymNode(field))
|
||||||
result.typ = field.typ
|
result.typ = field.typ
|
||||||
|
|
||||||
type
|
|
||||||
TCapture = seq[PSym]
|
|
||||||
|
|
||||||
proc Capture(cap: var TCapture, s: PSym) =
|
proc Capture(cap: var TCapture, s: PSym) =
|
||||||
for x in cap:
|
for x in cap:
|
||||||
if x.name.id == s.name.id: return
|
if x.name.id == s.name.id: return
|
||||||
|
|
@ -52,18 +63,21 @@ proc interestingVar(s: PSym): bool {.inline.} =
|
||||||
result = s.kind in {skVar, skLet, skTemp, skForVar, skParam, skResult} and
|
result = s.kind in {skVar, skLet, skTemp, skForVar, skParam, skResult} and
|
||||||
sfGlobal notin s.flags
|
sfGlobal notin s.flags
|
||||||
|
|
||||||
proc gatherVars(c: PTransf, n: PNode, outerProc: PSym, cap: var TCapture) =
|
proc gatherVars(c: PLLContext, n: PNode, cap: var TCapture) =
|
||||||
# gather used vars for closure generation into 'cap'
|
# gather used vars for closure generation into 'cap'
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkSym:
|
of nkSym:
|
||||||
var s = n.sym
|
var s = n.sym
|
||||||
if interestingVar(s) and outerProc.id == s.owner.id:
|
if interestingVar(s) and c.innerProc.id != s.owner.id:
|
||||||
|
# we need to compute the path here:
|
||||||
|
var
|
||||||
|
|
||||||
#echo "captured: ", s.name.s
|
#echo "captured: ", s.name.s
|
||||||
Capture(cap, s)
|
Capture(cap, s)
|
||||||
of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit: nil
|
of nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit: nil
|
||||||
else:
|
else:
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
gatherVars(c, n.sons[i], outerProc, cap)
|
gatherVars(c, n.sons[i], cap)
|
||||||
|
|
||||||
proc replaceVars(c: PTransf, n: PNode, outerProc, env: PSym) =
|
proc replaceVars(c: PTransf, n: PNode, outerProc, env: PSym) =
|
||||||
for i in countup(0, safeLen(n) - 1):
|
for i in countup(0, safeLen(n) - 1):
|
||||||
|
|
|
||||||
|
|
@ -279,7 +279,7 @@ proc transformBreak(c: PTransf, n: PNode): PTransNode =
|
||||||
result[0] = newSymNode(labl).PTransNode
|
result[0] = newSymNode(labl).PTransNode
|
||||||
|
|
||||||
proc transformLoopBody(c: PTransf, n: PNode): PTransNode =
|
proc transformLoopBody(c: PTransf, n: PNode): PTransNode =
|
||||||
# XXX BUG: What if it contains "continue" and "break"? "break" needs
|
# What if it contains "continue" and "break"? "break" needs
|
||||||
# an explicit label too, but not the same!
|
# an explicit label too, but not the same!
|
||||||
|
|
||||||
# We fix this here by making every 'break' belong to its enclosing loop
|
# We fix this here by making every 'break' belong to its enclosing loop
|
||||||
|
|
@ -638,17 +638,7 @@ proc transform(c: PTransf, n: PNode): PTransNode =
|
||||||
# nothing to be done for leaves:
|
# nothing to be done for leaves:
|
||||||
result = PTransNode(n)
|
result = PTransNode(n)
|
||||||
of nkBracketExpr: result = transformArrayAccess(c, n)
|
of nkBracketExpr: result = transformArrayAccess(c, n)
|
||||||
of procDefs:
|
of procDefs, nkMacroDef:
|
||||||
if c.nestedProcs == 0:
|
|
||||||
inc c.nestedProcs
|
|
||||||
result = transformProc(c, n)
|
|
||||||
dec c.nestedProcs
|
|
||||||
else:
|
|
||||||
result = PTransNode(n)
|
|
||||||
if n.sons[namePos].kind == nkSym:
|
|
||||||
let x = transformSym(c, n.sons[namePos])
|
|
||||||
if x.pnode.kind == nkClosure: result = x
|
|
||||||
of nkMacroDef:
|
|
||||||
# XXX no proper closure support yet:
|
# XXX no proper closure support yet:
|
||||||
if n.sons[genericParamsPos].kind == nkEmpty:
|
if n.sons[genericParamsPos].kind == nkEmpty:
|
||||||
var s = n.sons[namePos].sym
|
var s = n.sons[namePos].sym
|
||||||
|
|
|
||||||
3
todo.txt
3
todo.txt
|
|
@ -1,7 +1,6 @@
|
||||||
version 0.9.0
|
version 0.9.0
|
||||||
=============
|
=============
|
||||||
|
|
||||||
- implement 'gorge'
|
|
||||||
- implement a warning message for shadowed 'result' variable
|
- implement a warning message for shadowed 'result' variable
|
||||||
- make templates hygienic by default: try to gensym() everything in the 'block'
|
- make templates hygienic by default: try to gensym() everything in the 'block'
|
||||||
of a template
|
of a template
|
||||||
|
|
@ -39,6 +38,8 @@ version 0.9.0
|
||||||
Bugs
|
Bugs
|
||||||
----
|
----
|
||||||
|
|
||||||
|
- result.tzname = if local: getTzname()[if result.isDST: 0 else: 1] else: "UTC"
|
||||||
|
Crashes the compiler.
|
||||||
- bug: stress testing basic method example (eval example)
|
- bug: stress testing basic method example (eval example)
|
||||||
without ``-d:release`` leaks memory?
|
without ``-d:release`` leaks memory?
|
||||||
- bug: pragma statements in combination with symbol files are evaluated twice
|
- bug: pragma statements in combination with symbol files are evaluated twice
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue