removes 'x is iterator' special casing in the language

This commit is contained in:
Araq
2015-12-03 01:07:51 +01:00
parent 50e83d6433
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
t.callConv == ccClosure and
tfIterator notin t.flags))
else: discard
else:
result = newIntNode(nkIntLit, 0)
else:
var t2 = n[2].typ.skipTypes({tyTypeDesc})
maybeLiftType(t2, c, n.info)
@@ -1434,20 +1435,15 @@ proc semYield(c: PContext, n: PNode): PNode =
var iterType = c.p.owner.typ
let restype = iterType.sons[0]
if restype != nil:
let adjustedRes = if restype.kind == tyIter: restype.base
else: restype
if adjustedRes.kind != tyExpr:
n.sons[0] = fitNode(c, adjustedRes, n.sons[0])
if restype.kind != tyExpr:
n.sons[0] = fitNode(c, restype, n.sons[0])
if n.sons[0].typ == nil: internalError(n.info, "semYield")
if resultTypeIsInferrable(adjustedRes):
if resultTypeIsInferrable(restype):
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:
localError(n.info, errCannotReturnExpr)
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")
result = semExpr(c, n.sons[0], flags)
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 = symNodeFromType(c, typ, n.info)
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)
if isTupleType(tupexp):
# 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)
else:
result = tupexp

View File

@@ -540,7 +540,7 @@ proc symForVar(c: PContext, n: PNode): PSym =
proc semForVars(c: PContext, n: PNode): PNode =
result = 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})
# length == 3 means that there is one for loop variable
# and thus no tuple unpacking:
@@ -594,8 +594,7 @@ proc semFor(c: PContext, n: PNode): PNode =
result.kind = nkParForStmt
else:
result = semForFields(c, n, call.sons[0].sym.magic)
elif (isCallExpr and call.sons[0].typ.callConv == ccClosure) or
call.typ.kind == tyIter:
elif isCallExpr and call.sons[0].typ.callConv == ccClosure:
# first class iterator:
result = semForVars(c, n)
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 = 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:
if paramType.lastSon.kind == tyUserTypeClass:
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)
# we don't need to change the return type to iter[T]
result.flags.incl tfIterator
#if not r.isInlineIterator: r = newTypeWithSons(c, tyIter, @[r])
# XXX Would be nice if we could get rid of this
result.sons[0] = 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``.
checkSonsLen(n, 1)
let typExpr = semExprWithType(c, n.sons[0], {efInTypeof})
result = typExpr.typ.skipTypes({tyIter})
result = typExpr.typ
of nkPar:
if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev)
else:
@@ -1220,7 +1210,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
elif op.id == ord(wType):
checkSonsLen(n, 2)
let typExpr = semExprWithType(c, n.sons[1], {efInTypeof})
result = typExpr.typ.skipTypes({tyIter})
result = typExpr.typ
else:
result = semTypeExpr(c, n)
of nkWhenStmt:
@@ -1301,14 +1291,16 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
result.flags.incl tfHasStatic
of nkIteratorTy:
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:
result = semProcTypeWithScope(c, n, prev, skClosureIterator)
result.flags.incl(tfIterator)
if n.lastSon.kind == nkPragma and hasPragma(n.lastSon, wInline):
result.kind = tyIter
result.callConv = ccInline
else:
result.flags.incl(tfIterator)
result.callConv = ccClosure
of nkProcTy:
if n.sonsLen == 0:

View File

@@ -77,7 +77,7 @@ proc cacheTypeInst*(inst: PType) =
# update the refcount
let gt = inst.sons[0]
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
gt.sym.typeInstCache.safeAdd(inst)
@@ -390,7 +390,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
result = t
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))
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))
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) =
case r
of isConvertible, isIntConv: inc(m.convMatches, convMatch)
@@ -1323,13 +1319,6 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType,
else:
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.
# bothMetaCounter is for safety to avoid any infinite loop,
# 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
return result
c.breakSyms.add(labl)
if call.typ.kind != tyIter and
(call.kind notin nkCallKinds or call.sons[0].kind != nkSym or
call.sons[0].sym.kind != skIterator):
if call.kind notin nkCallKinds or call.sons[0].kind != nkSym or
call.sons[0].sym.kind != skIterator:
n.sons[length-1] = transformLoopBody(c, n.sons[length-1]).PNode
result[1] = lambdalifting.liftForLoop(n).PTransNode
discard c.breakSyms.pop
@@ -512,7 +511,6 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
for i in countup(1, sonsLen(call) - 1):
var arg = transform(c, call.sons[i]).PNode
var formal = skipTypes(iter.typ, abstractInst).n.sons[i].sym
if arg.typ.kind == tyIter: continue
case putArgInto(arg, formal.typ)
of paDirectMapping:
idNodeTablePut(newC.mapping, formal, arg)

View File

@@ -213,7 +213,7 @@ Concepts are written in the following form:
Container[T] = concept c
c.len is Ordinal
items(c) is iterator
items(c) is T
for value in c:
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
# 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):
import arch

View File

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

View File

@@ -16,6 +16,9 @@ News
actually work with the bool datatype.
- when compiling to JS, ``Node``, ``NodeType`` and ``Document`` are no longer
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