next steps for first class iterators
This commit is contained in:
parent
538699a281
commit
dd9ad9e497
7 changed files with 16 additions and 7 deletions
|
|
@ -888,7 +888,13 @@ proc evalIsOp*(n: PNode): PNode =
|
||||||
of "closure":
|
of "closure":
|
||||||
let t = skipTypes(t1, abstractRange)
|
let t = skipTypes(t1, abstractRange)
|
||||||
result = newIntNode(nkIntLit, ord(t.kind == tyProc and
|
result = newIntNode(nkIntLit, ord(t.kind == tyProc and
|
||||||
t.callConv == ccClosure))
|
t.callConv == ccClosure and
|
||||||
|
tfIterator notin t.flags))
|
||||||
|
of "iterator":
|
||||||
|
let t = skipTypes(t1, abstractRange)
|
||||||
|
result = newIntNode(nkIntLit, ord(t.kind == tyProc and
|
||||||
|
t.callConv == ccClosure and
|
||||||
|
tfIterator in t.flags))
|
||||||
else:
|
else:
|
||||||
let t2 = n[2].typ
|
let t2 = n[2].typ
|
||||||
var match = if t2.kind == tyTypeClass: matchTypeClass(t2, t1)
|
var match = if t2.kind == tyTypeClass: matchTypeClass(t2, t1)
|
||||||
|
|
|
||||||
|
|
@ -738,7 +738,7 @@ proc isExprStart(p: TParser): bool =
|
||||||
of tkSymbol, tkAccent, tkOpr, tkNot, tkNil, tkCast, tkIf,
|
of tkSymbol, tkAccent, tkOpr, tkNot, tkNil, tkCast, tkIf,
|
||||||
tkProc, tkIterator, tkBind,
|
tkProc, tkIterator, tkBind,
|
||||||
tkParLe, tkBracketLe, tkCurlyLe, tkIntLit..tkCharLit, tkVar, tkRef, tkPtr,
|
tkParLe, tkBracketLe, tkCurlyLe, tkIntLit..tkCharLit, tkVar, tkRef, tkPtr,
|
||||||
tkTuple, tkType, tkWhen, tkCase:
|
tkTuple, tkType, tkWhen, tkCase, tkShared:
|
||||||
result = true
|
result = true
|
||||||
else: result = false
|
else: result = false
|
||||||
|
|
||||||
|
|
@ -788,6 +788,7 @@ proc primary(p: var TParser, mode: TPrimaryMode): PNode =
|
||||||
of tkVar: result = parseTypeDescKAux(p, nkVarTy, mode)
|
of tkVar: result = parseTypeDescKAux(p, nkVarTy, mode)
|
||||||
of tkRef: result = parseTypeDescKAux(p, nkRefTy, mode)
|
of tkRef: result = parseTypeDescKAux(p, nkRefTy, mode)
|
||||||
of tkPtr: result = parseTypeDescKAux(p, nkPtrTy, mode)
|
of tkPtr: result = parseTypeDescKAux(p, nkPtrTy, mode)
|
||||||
|
of tkShared: result = parseTypeDescKAux(p, nkSharedTy, mode)
|
||||||
of tkType: result = parseTypeDescKAux(p, nkTypeOfExpr, mode)
|
of tkType: result = parseTypeDescKAux(p, nkTypeOfExpr, mode)
|
||||||
of tkTuple: result = parseTuple(p)
|
of tkTuple: result = parseTuple(p)
|
||||||
of tkProc: result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef})
|
of tkProc: result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef})
|
||||||
|
|
|
||||||
|
|
@ -744,11 +744,12 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
rawAddSon(s.typ, nil)
|
rawAddSon(s.typ, nil)
|
||||||
if n.sons[patternPos].kind != nkEmpty:
|
if n.sons[patternPos].kind != nkEmpty:
|
||||||
n.sons[patternPos] = semPattern(c, n.sons[patternPos])
|
n.sons[patternPos] = semPattern(c, n.sons[patternPos])
|
||||||
|
if s.kind == skIterator: s.typ.flags.incl(tfIterator)
|
||||||
|
|
||||||
var proto = SearchForProc(c, s, c.tab.tos-2) # -2 because we have a scope
|
var proto = SearchForProc(c, s, c.tab.tos-2) # -2 because we have a scope
|
||||||
# open for parameters
|
# open for parameters
|
||||||
if proto == nil:
|
if proto == nil:
|
||||||
s.typ.callConv = lastOptionEntry(c).defaultCC
|
s.typ.callConv = lastOptionEntry(c).defaultCC
|
||||||
# add it here, so that recursive procs are possible:
|
# add it here, so that recursive procs are possible:
|
||||||
# -2 because we have a scope open for parameters
|
# -2 because we have a scope open for parameters
|
||||||
if sfGenSym in s.flags: nil
|
if sfGenSym in s.flags: nil
|
||||||
|
|
|
||||||
|
|
@ -911,6 +911,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
closeScope(c.tab)
|
closeScope(c.tab)
|
||||||
if n.kind == nkIteratorTy:
|
if n.kind == nkIteratorTy:
|
||||||
result.flags.incl(tfIterator)
|
result.flags.incl(tfIterator)
|
||||||
|
result.callConv = ccClosure
|
||||||
of nkEnumTy: result = semEnum(c, n, prev)
|
of nkEnumTy: result = semEnum(c, n, prev)
|
||||||
of nkType: result = n.typ
|
of nkType: result = n.typ
|
||||||
of nkStmtListType: result = semStmtListType(c, n, prev)
|
of nkStmtListType: result = semStmtListType(c, n, prev)
|
||||||
|
|
|
||||||
|
|
@ -293,6 +293,8 @@ proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation =
|
||||||
elif tfThread in f.flags and a.flags * {tfThread, tfNoSideEffect} == {}:
|
elif tfThread in f.flags and a.flags * {tfThread, tfNoSideEffect} == {}:
|
||||||
# noSideEffect implies ``tfThread``! XXX really?
|
# noSideEffect implies ``tfThread``! XXX really?
|
||||||
return isNone
|
return isNone
|
||||||
|
elif f.flags * {tfIterator} != a.flags * {tfIterator}:
|
||||||
|
return isNone
|
||||||
elif f.callconv != a.callconv:
|
elif f.callconv != a.callconv:
|
||||||
# valid to pass a 'nimcall' thingie to 'closure':
|
# valid to pass a 'nimcall' thingie to 'closure':
|
||||||
if f.callconv == ccClosure and a.callconv == ccDefault:
|
if f.callconv == ccClosure and a.callconv == ccDefault:
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ iterator count2(): int {.closure.} =
|
||||||
|
|
||||||
# a first class iterator has the type 'proc {.closure.}', but maybe
|
# a first class iterator has the type 'proc {.closure.}', but maybe
|
||||||
# it shouldn't:
|
# it shouldn't:
|
||||||
proc invoke(iter: proc(): int {.closure.}) =
|
proc invoke(iter: iterator(): int {.closure.}) =
|
||||||
for x in iter(): echo x
|
for x in iter(): echo x
|
||||||
|
|
||||||
invoke(count0)
|
invoke(count0)
|
||||||
|
|
@ -88,7 +88,7 @@ invoke(count2)
|
||||||
|
|
||||||
# simple tasking:
|
# simple tasking:
|
||||||
type
|
type
|
||||||
TTask = proc (ticker: int) {.closure.}
|
TTask = iterator (ticker: int)
|
||||||
|
|
||||||
iterator a1(ticker: int) {.closure.} =
|
iterator a1(ticker: int) {.closure.} =
|
||||||
echo "a1: A"
|
echo "a1: A"
|
||||||
|
|
|
||||||
2
todo.txt
2
todo.txt
|
|
@ -2,7 +2,6 @@ version 0.9.2
|
||||||
=============
|
=============
|
||||||
|
|
||||||
- test&finish first class iterators:
|
- test&finish first class iterators:
|
||||||
* tyIterator: implement nkIteratorTy, nkSharedTy
|
|
||||||
* allow return in first class iterators
|
* allow return in first class iterators
|
||||||
* nested iterators
|
* nested iterators
|
||||||
* arglist as a type?
|
* arglist as a type?
|
||||||
|
|
@ -34,7 +33,6 @@ Bugs
|
||||||
- bug: the parser is not strict enough with newlines: 'echo "a" echo "b"'
|
- bug: the parser is not strict enough with newlines: 'echo "a" echo "b"'
|
||||||
compiles
|
compiles
|
||||||
- bug: blocks can "export" an identifier but the CCG generates {} for them ...
|
- bug: blocks can "export" an identifier but the CCG generates {} for them ...
|
||||||
- bug: what if we pass an iterator to a proc var? iterators use tyProc too ...
|
|
||||||
|
|
||||||
|
|
||||||
version 0.9.XX
|
version 0.9.XX
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue