removes 'x is iterator' special casing in the language
This commit is contained in:
parent
50e83d6433
commit
760242b870
10 changed files with 29 additions and 50 deletions
|
|
@ -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:
|
iterType.sons[0] = inferred
|
||||||
restype.sons[0] = inferred
|
|
||||||
else:
|
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue