removes 'x is iterator' special casing in the language

This commit is contained in:
Araq 2015-12-03 01:07:51 +01:00
commit 760242b870
10 changed files with 29 additions and 50 deletions

View file

@ -385,7 +385,8 @@ proc isOpImpl(c: PContext, n: PNode): PNode =
result = newIntNode(nkIntLit, ord(t.kind == tyProc and result = newIntNode(nkIntLit, ord(t.kind == tyProc and
t.callConv == ccClosure and t.callConv == ccClosure and
tfIterator notin t.flags)) tfIterator notin t.flags))
else: discard else:
result = newIntNode(nkIntLit, 0)
else: else:
var t2 = n[2].typ.skipTypes({tyTypeDesc}) var t2 = n[2].typ.skipTypes({tyTypeDesc})
maybeLiftType(t2, c, n.info) maybeLiftType(t2, c, n.info)
@ -1434,20 +1435,15 @@ proc semYield(c: PContext, n: PNode): PNode =
var iterType = c.p.owner.typ var iterType = c.p.owner.typ
let restype = iterType.sons[0] let restype = iterType.sons[0]
if restype != nil: if restype != nil:
let adjustedRes = if restype.kind == tyIter: restype.base if restype.kind != tyExpr:
else: restype n.sons[0] = fitNode(c, restype, n.sons[0])
if adjustedRes.kind != tyExpr:
n.sons[0] = fitNode(c, adjustedRes, n.sons[0])
if n.sons[0].typ == nil: internalError(n.info, "semYield") if n.sons[0].typ == nil: internalError(n.info, "semYield")
if resultTypeIsInferrable(adjustedRes): if resultTypeIsInferrable(restype):
let inferred = n.sons[0].typ let inferred = n.sons[0].typ
if restype.kind == tyIter:
restype.sons[0] = inferred
else:
iterType.sons[0] = inferred iterType.sons[0] = inferred
semYieldVarResult(c, n, adjustedRes) semYieldVarResult(c, n, restype)
else: else:
localError(n.info, errCannotReturnExpr) localError(n.info, errCannotReturnExpr)
elif c.p.owner.typ.sons[0] != nil: elif c.p.owner.typ.sons[0] != nil:
@ -2184,7 +2180,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
message(n.info, warnDeprecated, "bind") message(n.info, warnDeprecated, "bind")
result = semExpr(c, n.sons[0], flags) result = semExpr(c, n.sons[0], flags)
of nkTypeOfExpr, nkTupleTy, nkTupleClassTy, nkRefTy..nkEnumTy, nkStaticTy: of nkTypeOfExpr, nkTupleTy, nkTupleClassTy, nkRefTy..nkEnumTy, nkStaticTy:
var typ = semTypeNode(c, n, nil).skipTypes({tyTypeDesc, tyIter}) var typ = semTypeNode(c, n, nil).skipTypes({tyTypeDesc})
result.typ = makeTypeDesc(c, typ) result.typ = makeTypeDesc(c, typ)
#result = symNodeFromType(c, typ, n.info) #result = symNodeFromType(c, typ, n.info)
of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit: of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit:
@ -2257,7 +2253,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
var tupexp = semTuplePositionsConstr(c, n, flags) var tupexp = semTuplePositionsConstr(c, n, flags)
if isTupleType(tupexp): if isTupleType(tupexp):
# reinterpret as type # reinterpret as type
var typ = semTypeNode(c, n, nil).skipTypes({tyTypeDesc, tyIter}) var typ = semTypeNode(c, n, nil).skipTypes({tyTypeDesc})
result.typ = makeTypeDesc(c, typ) result.typ = makeTypeDesc(c, typ)
else: else:
result = tupexp result = tupexp

View file

@ -540,7 +540,7 @@ proc symForVar(c: PContext, n: PNode): PSym =
proc semForVars(c: PContext, n: PNode): PNode = proc semForVars(c: PContext, n: PNode): PNode =
result = n result = n
var length = sonsLen(n) var length = sonsLen(n)
let iterBase = n.sons[length-2].typ.skipTypes({tyIter}) let iterBase = n.sons[length-2].typ
var iter = skipTypes(iterBase, {tyGenericInst}) var iter = skipTypes(iterBase, {tyGenericInst})
# length == 3 means that there is one for loop variable # length == 3 means that there is one for loop variable
# and thus no tuple unpacking: # and thus no tuple unpacking:
@ -594,8 +594,7 @@ proc semFor(c: PContext, n: PNode): PNode =
result.kind = nkParForStmt result.kind = nkParForStmt
else: else:
result = semForFields(c, n, call.sons[0].sym.magic) result = semForFields(c, n, call.sons[0].sym.magic)
elif (isCallExpr and call.sons[0].typ.callConv == ccClosure) or elif isCallExpr and call.sons[0].typ.callConv == ccClosure:
call.typ.kind == tyIter:
# first class iterator: # first class iterator:
result = semForVars(c, n) result = semForVars(c, n)
elif not isCallExpr or call.sons[0].kind != nkSym or elif not isCallExpr or call.sons[0].kind != nkSym or

View file

@ -832,15 +832,6 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
result = newTypeWithSons(c, tyCompositeTypeClass, @[paramType, result]) result = newTypeWithSons(c, tyCompositeTypeClass, @[paramType, result])
result = addImplicitGeneric(result) result = addImplicitGeneric(result)
of tyIter:
if paramType.callConv == ccInline:
if procKind notin {skTemplate, skMacro, skIterator}:
localError(info, errInlineIteratorsAsProcParams)
if paramType.len == 1:
let lifted = liftingWalk(paramType.base)
if lifted != nil: paramType.sons[0] = lifted
result = addImplicitGeneric(paramType)
of tyGenericInst: of tyGenericInst:
if paramType.lastSon.kind == tyUserTypeClass: if paramType.lastSon.kind == tyUserTypeClass:
var cp = copyType(paramType, getCurrOwner(), false) var cp = copyType(paramType, getCurrOwner(), false)
@ -998,7 +989,6 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
# in cases like iterator foo(it: iterator): type(it) # in cases like iterator foo(it: iterator): type(it)
# we don't need to change the return type to iter[T] # we don't need to change the return type to iter[T]
result.flags.incl tfIterator result.flags.incl tfIterator
#if not r.isInlineIterator: r = newTypeWithSons(c, tyIter, @[r])
# XXX Would be nice if we could get rid of this # XXX Would be nice if we could get rid of this
result.sons[0] = r result.sons[0] = r
result.n.typ = r result.n.typ = r
@ -1154,7 +1144,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
# for ``type(countup(1,3))``, see ``tests/ttoseq``. # for ``type(countup(1,3))``, see ``tests/ttoseq``.
checkSonsLen(n, 1) checkSonsLen(n, 1)
let typExpr = semExprWithType(c, n.sons[0], {efInTypeof}) let typExpr = semExprWithType(c, n.sons[0], {efInTypeof})
result = typExpr.typ.skipTypes({tyIter}) result = typExpr.typ
of nkPar: of nkPar:
if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev) if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev)
else: else:
@ -1220,7 +1210,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
elif op.id == ord(wType): elif op.id == ord(wType):
checkSonsLen(n, 2) checkSonsLen(n, 2)
let typExpr = semExprWithType(c, n.sons[1], {efInTypeof}) let typExpr = semExprWithType(c, n.sons[1], {efInTypeof})
result = typExpr.typ.skipTypes({tyIter}) result = typExpr.typ
else: else:
result = semTypeExpr(c, n) result = semTypeExpr(c, n)
of nkWhenStmt: of nkWhenStmt:
@ -1301,14 +1291,16 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
result.flags.incl tfHasStatic result.flags.incl tfHasStatic
of nkIteratorTy: of nkIteratorTy:
if n.sonsLen == 0: if n.sonsLen == 0:
result = newConstraint(c, tyIter) result = newTypeS(tyBuiltInTypeClass, c)
let child = newTypeS(tyProc, c)
child.flags.incl tfIterator
result.addSonSkipIntLit(child)
else: else:
result = semProcTypeWithScope(c, n, prev, skClosureIterator) result = semProcTypeWithScope(c, n, prev, skClosureIterator)
result.flags.incl(tfIterator)
if n.lastSon.kind == nkPragma and hasPragma(n.lastSon, wInline): if n.lastSon.kind == nkPragma and hasPragma(n.lastSon, wInline):
result.kind = tyIter
result.callConv = ccInline result.callConv = ccInline
else: else:
result.flags.incl(tfIterator)
result.callConv = ccClosure result.callConv = ccClosure
of nkProcTy: of nkProcTy:
if n.sonsLen == 0: if n.sonsLen == 0:

View file

@ -77,7 +77,7 @@ proc cacheTypeInst*(inst: PType) =
# update the refcount # update the refcount
let gt = inst.sons[0] let gt = inst.sons[0]
let t = if gt.kind == tyGenericBody: gt.lastSon else: gt let t = if gt.kind == tyGenericBody: gt.lastSon else: gt
if t.kind in {tyStatic, tyGenericParam, tyIter} + tyTypeClasses: if t.kind in {tyStatic, tyGenericParam} + tyTypeClasses:
return return
gt.sym.typeInstCache.safeAdd(inst) gt.sym.typeInstCache.safeAdd(inst)
@ -390,7 +390,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
result = t result = t
if t == nil: return if t == nil: return
if t.kind in {tyStatic, tyGenericParam, tyIter} + tyTypeClasses: if t.kind in {tyStatic, tyGenericParam} + tyTypeClasses:
let lookup = PType(idTableGet(cl.typeMap, t)) let lookup = PType(idTableGet(cl.typeMap, t))
if lookup != nil: return lookup if lookup != nil: return lookup

View file

@ -1256,10 +1256,6 @@ proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType,
result.typ = getInstantiatedType(c, arg, m, base(f)) result.typ = getInstantiatedType(c, arg, m, base(f))
m.baseTypeMatch = true m.baseTypeMatch = true
proc isInlineIterator*(t: PType): bool =
result = t.kind == tyIter or
(t.kind == tyBuiltInTypeClass and t.base.kind == tyIter)
proc incMatches(m: var TCandidate; r: TTypeRelation; convMatch = 1) = proc incMatches(m: var TCandidate; r: TTypeRelation; convMatch = 1) =
case r case r
of isConvertible, isIntConv: inc(m.convMatches, convMatch) of isConvertible, isIntConv: inc(m.convMatches, convMatch)
@ -1323,13 +1319,6 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType,
else: else:
return argSemantized # argOrig return argSemantized # argOrig
if r != isNone and f.isInlineIterator:
var inlined = newTypeS(tyStatic, c)
inlined.sons = @[argType]
inlined.n = argSemantized
put(m.bindings, f, inlined)
return argSemantized
# If r == isBothMetaConvertible then we rerun typeRel. # If r == isBothMetaConvertible then we rerun typeRel.
# bothMetaCounter is for safety to avoid any infinite loop, # bothMetaCounter is for safety to avoid any infinite loop,
# I don't have any example when it is needed. # I don't have any example when it is needed.

View file

@ -478,9 +478,8 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
result[1] = newNode(nkEmpty).PTransNode result[1] = newNode(nkEmpty).PTransNode
return result return result
c.breakSyms.add(labl) c.breakSyms.add(labl)
if call.typ.kind != tyIter and if call.kind notin nkCallKinds or call.sons[0].kind != nkSym or
(call.kind notin nkCallKinds or call.sons[0].kind != nkSym or call.sons[0].sym.kind != skIterator:
call.sons[0].sym.kind != skIterator):
n.sons[length-1] = transformLoopBody(c, n.sons[length-1]).PNode n.sons[length-1] = transformLoopBody(c, n.sons[length-1]).PNode
result[1] = lambdalifting.liftForLoop(n).PTransNode result[1] = lambdalifting.liftForLoop(n).PTransNode
discard c.breakSyms.pop discard c.breakSyms.pop
@ -512,7 +511,6 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
for i in countup(1, sonsLen(call) - 1): for i in countup(1, sonsLen(call) - 1):
var arg = transform(c, call.sons[i]).PNode var arg = transform(c, call.sons[i]).PNode
var formal = skipTypes(iter.typ, abstractInst).n.sons[i].sym var formal = skipTypes(iter.typ, abstractInst).n.sons[i].sym
if arg.typ.kind == tyIter: continue
case putArgInto(arg, formal.typ) case putArgInto(arg, formal.typ)
of paDirectMapping: of paDirectMapping:
idNodeTablePut(newC.mapping, formal, arg) idNodeTablePut(newC.mapping, formal, arg)

View file

@ -213,7 +213,7 @@ Concepts are written in the following form:
Container[T] = concept c Container[T] = concept c
c.len is Ordinal c.len is Ordinal
items(c) is iterator items(c) is T
for value in c: for value in c:
type(value) is T type(value) is T

View file

@ -13,6 +13,8 @@
# and sweep GC to free cycles. It is hard realtime in that if you play # and sweep GC to free cycles. It is hard realtime in that if you play
# according to its rules, no deadline will ever be missed. # according to its rules, no deadline will ever be missed.
# XXX Ensure by smart color masking that the object is not in the ZCT.
when defined(nimCoroutines): when defined(nimCoroutines):
import arch import arch

View file

@ -23,7 +23,7 @@ template reject(e: expr) =
type type
Container[T] = concept c Container[T] = concept c
c.len is Ordinal c.len is Ordinal
items(c) is iterator items(c) is T
for value in c: for value in c:
type(value) is T type(value) is T

View file

@ -16,6 +16,9 @@ News
actually work with the bool datatype. actually work with the bool datatype.
- when compiling to JS, ``Node``, ``NodeType`` and ``Document`` are no longer - when compiling to JS, ``Node``, ``NodeType`` and ``Document`` are no longer
defined. Use the types defined in ``dom.nim`` instead. defined. Use the types defined in ``dom.nim`` instead.
- The check ``x is iterator`` (used for instance in concepts) was always a
weird special case (you could not use ``x is proc``) and was removed from
the language.
2015-10-27 Version 0.12.0 released 2015-10-27 Version 0.12.0 released