From ce91a1b25db6e121cfe1f5ce3e5f4d61c80361e7 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Thu, 28 Jul 2016 21:35:00 +0200 Subject: fixes #4510 --- compiler/suggest.nim | 2 ++ 1 file changed, 2 insertions(+) (limited to 'compiler/suggest.nim') diff --git a/compiler/suggest.nim b/compiler/suggest.nim index bcab6b04a..f35ff2142 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -393,6 +393,8 @@ proc suggestSym*(info: TLineInfo; s: PSym; isDecl=true) {.inline.} = proc markUsed(info: TLineInfo; s: PSym) = incl(s.flags, sfUsed) + if s.kind == skEnumField and s.owner != nil: + incl(s.owner.flags, sfUsed) if {sfDeprecated, sfError} * s.flags != {}: if sfDeprecated in s.flags: message(info, warnDeprecated, s.name.s) if sfError in s.flags: localError(info, errWrongSymbolX, s.name.s) -- cgit 1.4.1-2-gfad0 From 60b187513ed8e2a061816a912e372a1c81794d50 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Fri, 29 Jul 2016 17:35:51 +0200 Subject: stdlib and compiler don't use .immediate anymore --- compiler/ast.nim | 2 ++ compiler/ccgmerge.nim | 2 +- compiler/ccgstmts.nim | 2 +- compiler/extccomp.nim | 2 +- compiler/jsgen.nim | 2 +- compiler/parser.nim | 2 +- compiler/pragmas.nim | 5 ++- compiler/semfold.nim | 4 +-- compiler/semgnrc.nim | 9 ++++-- compiler/semparallel.nim | 2 +- compiler/semtempl.nim | 8 +++-- compiler/sigmatch.nim | 6 ++-- compiler/suggest.nim | 2 +- compiler/types.nim | 2 +- compiler/vm.nim | 19 ++++++------ compiler/vmdef.nim | 12 ++++---- compiler/vmgen.nim | 4 +-- compiler/vmhooks.nim | 4 +-- compiler/vmops.nim | 16 +++++----- lib/core/macros.nim | 17 +++++----- lib/impure/nre.nim | 6 ++-- lib/pure/asyncdispatch.nim | 8 ++--- lib/pure/collections/sequtils.nim | 24 +++++++-------- lib/pure/collections/sets.nim | 4 +-- lib/pure/collections/tableimpl.nim | 14 ++++----- lib/pure/collections/tables.nim | 16 +++++----- lib/pure/future.nim | 6 ++-- lib/pure/net.nim | 4 +-- lib/pure/os.nim | 18 +++++------ lib/pure/strutils.nim | 2 +- lib/pure/times.nim | 63 +++++++++++++------------------------- lib/pure/unittest.nim | 18 +++++------ lib/system.nim | 26 ++++++++-------- tests/macros/tdumptree.nim | 2 +- todo.txt | 4 ++- web/news/version_0_15_released.rst | 4 +++ 36 files changed, 169 insertions(+), 172 deletions(-) (limited to 'compiler/suggest.nim') diff --git a/compiler/ast.nim b/compiler/ast.nim index 4c98219f9..8a3c76435 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -278,6 +278,8 @@ const sfImmediate* = sfDeadCodeElim # macro or template is immediately expanded # without considering any possible overloads + sfAllUntyped* = sfVolatile # macro or template is immediately expanded \ + # in a generic context sfDirty* = sfPure # template is not hygienic (old styled template) diff --git a/compiler/ccgmerge.nim b/compiler/ccgmerge.nim index 2e77cd2a6..1b2104174 100644 --- a/compiler/ccgmerge.nim +++ b/compiler/ccgmerge.nim @@ -229,7 +229,7 @@ proc processMergeInfo(L: var TBaseLexer, m: BModule) = when not defined(nimhygiene): {.pragma: inject.} -template withCFile(cfilename: string, body: stmt) {.immediate.} = +template withCFile(cfilename: string, body: untyped) = var s = llStreamOpen(cfilename, fmRead) if s == nil: return var L {.inject.}: TBaseLexer diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 70d50b060..4836527a2 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -136,7 +136,7 @@ proc exprBlock(p: BProc, n: PNode, d: var TLoc) = expr(p, n, d) endBlock(p) -template preserveBreakIdx(body: stmt): stmt {.immediate.} = +template preserveBreakIdx(body: untyped): untyped = var oldBreakIdx = p.breakIdx body p.breakIdx = oldBreakIdx diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index eb9aac490..2dcfc0226 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -61,7 +61,7 @@ type # When adding new compilers, the cmake sources could be a good reference: # http://cmake.org/gitweb?p=cmake.git;a=tree;f=Modules/Platform; -template compiler(name: expr, settings: stmt): stmt {.immediate.} = +template compiler(name, settings: untyped): untyped = proc name: TInfoCC {.compileTime.} = settings # GNU C and C++ Compiler diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index a60b0cc5e..244bba681 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -95,7 +95,7 @@ type up: PProc # up the call chain; required for closure support declaredGlobals: IntSet -template `|`(a, b: expr): expr {.immediate, dirty.} = +template `|`(a, b: untyped): untyped {.dirty.} = (if p.target == targetJS: a else: b) proc newGlobals(): PGlobals = diff --git a/compiler/parser.nim b/compiler/parser.nim index 8b20b56db..2623dea9e 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -98,7 +98,7 @@ proc parMessage(p: TParser, msg: TMsgKind, tok: TToken) = ## Produce and emit a parser message to output about the token `tok` parMessage(p, msg, prettyTok(tok)) -template withInd(p: expr, body: stmt) {.immediate.} = +template withInd(p, body: untyped) = let oldInd = p.currInd p.currInd = p.tok.indent body diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index d7d1ed838..50d5bb1b5 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -626,7 +626,10 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int, processImportCompilerProc(sym, getOptionalStr(c, it, "$1")) of wExtern: setExternName(sym, expectStrLit(c, it)) of wImmediate: - if sym.kind in {skTemplate, skMacro}: incl(sym.flags, sfImmediate) + if sym.kind in {skTemplate, skMacro}: + incl(sym.flags, sfImmediate) + incl(sym.flags, sfAllUntyped) + message(n.info, warnDeprecated, "use 'untyped' parameters instead; immediate") else: invalidPragma(it) of wDirty: if sym.kind == skTemplate: incl(sym.flags, sfDirty) diff --git a/compiler/semfold.nim b/compiler/semfold.nim index e9ee50d74..7c734e33b 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -143,7 +143,7 @@ proc getIntervalType*(m: TMagic, n: PNode): PType = const ordIntLit = {nkIntLit..nkUInt64Lit} result = n.typ - template commutativeOp(opr: expr) {.immediate.} = + template commutativeOp(opr: untyped) = let a = n.sons[1] let b = n.sons[2] if isIntRangeOrLit(a.typ) and isIntRangeOrLit(b.typ): @@ -151,7 +151,7 @@ proc getIntervalType*(m: TMagic, n: PNode): PType = opr(pickMinInt(a), pickMinInt(b)), opr(pickMaxInt(a), pickMaxInt(b))) - template binaryOp(opr: expr) {.immediate.} = + template binaryOp(opr: untyped) = let a = n.sons[1] let b = n.sons[2] if isIntRange(a.typ) and b.kind in {nkIntLit..nkUInt64Lit}: diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index b78679411..0fd2e546e 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -48,7 +48,10 @@ proc semGenericStmtScope(c: PContext, n: PNode, closeScope(c) template macroToExpand(s: expr): expr = - s.kind in {skMacro, skTemplate} and (s.typ.len == 1 or sfImmediate in s.flags) + s.kind in {skMacro, skTemplate} and (s.typ.len == 1 or sfAllUntyped in s.flags) + +template macroToExpandSym(s: expr): expr = + s.kind in {skMacro, skTemplate} and (s.typ.len == 1) proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym, ctx: var GenericCtx): PNode = @@ -61,14 +64,14 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym, of skProc, skMethod, skIterator, skConverter, skModule: result = symChoice(c, n, s, scOpen) of skTemplate: - if macroToExpand(s): + if macroToExpandSym(s): styleCheckUse(n.info, s) result = semTemplateExpr(c, n, s, {efNoSemCheck}) result = semGenericStmt(c, result, {}, ctx) else: result = symChoice(c, n, s, scOpen) of skMacro: - if macroToExpand(s): + if macroToExpandSym(s): styleCheckUse(n.info, s) result = semMacroExpr(c, n, n, s, {efNoSemCheck}) result = semGenericStmt(c, result, {}, ctx) diff --git a/compiler/semparallel.nim b/compiler/semparallel.nim index a4ec14250..21429a8d8 100644 --- a/compiler/semparallel.nim +++ b/compiler/semparallel.nim @@ -260,7 +260,7 @@ proc min(a, b: PNode): PNode = proc fromSystem(op: PSym): bool = sfSystemModule in getModule(op).flags -template pushSpawnId(c: expr, body: stmt) {.immediate, dirty.} = +template pushSpawnId(c, body) {.dirty.} = inc c.spawns let oldSpawnId = c.currentSpawnId c.currentSpawnId = c.spawns diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index a4498a3ae..3ee019674 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -577,13 +577,16 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = else: gp = newNodeI(nkGenericParams, n.info) # process parameters: + var allUntyped = true if n.sons[paramsPos].kind != nkEmpty: semParamList(c, n.sons[paramsPos], gp, s) # a template's parameters are not gensym'ed even if that was originally the # case as we determine whether it's a template parameter in the template # body by the absence of the sfGenSym flag: for i in 1 .. s.typ.n.len-1: - s.typ.n.sons[i].sym.flags.excl sfGenSym + let param = s.typ.n.sons[i].sym + param.flags.excl sfGenSym + if param.typ.kind != tyExpr: allUntyped = false if sonsLen(gp) > 0: if n.sons[genericParamsPos].kind == nkEmpty: # we have a list of implicit type parameters: @@ -599,6 +602,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = s.typ.n = newNodeI(nkFormalParams, n.info) rawAddSon(s.typ, newTypeS(tyStmt, c)) addSon(s.typ.n, newNodeIT(nkType, n.info, s.typ.sons[0])) + if allUntyped: incl(s.flags, sfAllUntyped) if n.sons[patternPos].kind != nkEmpty: n.sons[patternPos] = semPattern(c, n.sons[patternPos]) var ctx: TemplCtx @@ -629,7 +633,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = proc semPatternBody(c: var TemplCtx, n: PNode): PNode = template templToExpand(s: expr): expr = - s.kind == skTemplate and (s.typ.len == 1 or sfImmediate in s.flags) + s.kind == skTemplate and (s.typ.len == 1 or sfAllUntyped in s.flags) proc newParam(c: var TemplCtx, n: PNode, s: PSym): PNode = # the param added in the current scope is actually wrong here for diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 9a8f865a6..b8fd8bf1e 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -691,7 +691,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = put(c.bindings, f, bound) return res - template considerPreviousT(body: stmt) {.immediate.} = + template considerPreviousT(body: untyped) = var prev = PType(idTableGet(c.bindings, f)) if prev == nil: body else: return typeRel(c, prev, a) @@ -1591,7 +1591,7 @@ template isVarargsUntyped(x): expr = proc matchesAux(c: PContext, n, nOrig: PNode, m: var TCandidate, marker: var IntSet) = - template checkConstraint(n: expr) {.immediate, dirty.} = + template checkConstraint(n: untyped) {.dirty.} = if not formal.constraint.isNil: if matchNodeKinds(formal.constraint, n): # better match over other routines with no such restriction: @@ -1816,7 +1816,7 @@ proc instTypeBoundOp*(c: PContext; dc: PSym; t: PType; info: TLineInfo; include suggest when not declared(tests): - template tests(s: stmt) {.immediate.} = discard + template tests(s: untyped) = discard tests: var dummyOwner = newSym(skModule, getIdent("test_module"), nil, UnknownLineInfo()) diff --git a/compiler/suggest.nim b/compiler/suggest.nim index f35ff2142..c127b968c 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -138,7 +138,7 @@ proc suggestField(c: PContext, s: PSym, outputs: var int) = suggestResult(symToSuggest(s, isLocal=true, $ideSug, 100)) inc outputs -template wholeSymTab(cond, section: expr) {.immediate.} = +template wholeSymTab(cond, section: untyped) = var isLocal = true for scope in walkScopes(c.currentScope): if scope == c.topLevelScope: isLocal = false diff --git a/compiler/types.nim b/compiler/types.nim index 5fbab85b9..42ca0f9fc 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -806,7 +806,7 @@ proc sameTuple(a, b: PType, c: var TSameTypeClosure): bool = elif a.n != b.n and (a.n == nil or b.n == nil) and IgnoreTupleFields notin c.flags: result = false -template ifFastObjectTypeCheckFailed(a, b: PType, body: stmt) {.immediate.} = +template ifFastObjectTypeCheckFailed(a, b: PType, body: untyped) = if tfFromGeneric notin a.flags + b.flags: # fast case: id comparison suffices: result = a.id == b.id diff --git a/compiler/vm.nim b/compiler/vm.nim index f275b7b9b..ac4ea6ad9 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -92,34 +92,34 @@ when not defined(nimComputedGoto): proc myreset(n: var TFullReg) = reset(n) -template ensureKind(k: expr) {.immediate, dirty.} = +template ensureKind(k: untyped) {.dirty.} = if regs[ra].kind != k: myreset(regs[ra]) regs[ra].kind = k -template decodeB(k: expr) {.immediate, dirty.} = +template decodeB(k: untyped) {.dirty.} = let rb = instr.regB ensureKind(k) -template decodeBC(k: expr) {.immediate, dirty.} = +template decodeBC(k: untyped) {.dirty.} = let rb = instr.regB let rc = instr.regC ensureKind(k) -template declBC() {.immediate, dirty.} = +template declBC() {.dirty.} = let rb = instr.regB let rc = instr.regC -template decodeBImm(k: expr) {.immediate, dirty.} = +template decodeBImm(k: untyped) {.dirty.} = let rb = instr.regB let imm = instr.regC - byteExcess ensureKind(k) -template decodeBx(k: expr) {.immediate, dirty.} = +template decodeBx(k: expr) {.dirty.} = let rbx = instr.regBx - wordExcess ensureKind(k) -template move(a, b: expr) {.immediate, dirty.} = system.shallowCopy(a, b) +template move(a, b: untyped) {.dirty.} = system.shallowCopy(a, b) # XXX fix minor 'shallowCopy' overloading bug in compiler proc createStrKeepNode(x: var TFullReg; keepNode=true) = @@ -1573,7 +1573,7 @@ proc setupMacroParam(x: PNode, typ: PType): TFullReg = var evalMacroCounter: int proc evalMacroCall*(module: PSym, n, nOrig: PNode, sym: PSym): PNode = - # XXX GlobalError() is ugly here, but I don't know a better solution for now + # XXX globalError() is ugly here, but I don't know a better solution for now inc(evalMacroCounter) if evalMacroCounter > 100: globalError(n.info, errTemplateInstantiationTooNested) @@ -1603,7 +1603,7 @@ proc evalMacroCall*(module: PSym, n, nOrig: PNode, sym: PSym): PNode = # return value: tos.slots[0].kind = rkNode - tos.slots[0].node = newNodeIT(nkEmpty, n.info, sym.typ.sons[0]) + tos.slots[0].node = newNodeI(nkEmpty, n.info) # setup parameters: for i in 1.. = r and r > j) or (r > j and j > i) or (j > i and i >= r)): + doWhile((i >= r and r > j) or (r > j and j > i) or (j > i and i >= r)): i = (i + 1) and msk # increment mod table size if isEmpty(s.data[i].hcode): # end of collision cluster; So all done return @@ -615,7 +615,7 @@ proc card*[A](s: OrderedSet[A]): int {.inline.} = ## `_ of a set. result = s.counter -template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} = +template forAllOrderedPairs(yieldStmt: untyped) {.dirty.} = var h = s.first while h >= 0: var nxt = s.data[h].next diff --git a/lib/pure/collections/tableimpl.nim b/lib/pure/collections/tableimpl.nim index 1bbf19ee9..f4a135e01 100644 --- a/lib/pure/collections/tableimpl.nim +++ b/lib/pure/collections/tableimpl.nim @@ -72,14 +72,14 @@ proc rawInsert[X, A, B](t: var X, data: var KeyValuePairSeq[A, B], key: A, val: B, hc: Hash, h: Hash) = rawInsertImpl() -template addImpl(enlarge) {.dirty, immediate.} = +template addImpl(enlarge) {.dirty.} = if mustRehash(t.dataLen, t.counter): enlarge(t) var hc: Hash var j = rawGetDeep(t, key, hc) rawInsert(t, t.data, key, val, hc, j) inc(t.counter) -template maybeRehashPutImpl(enlarge) {.dirty, immediate.} = +template maybeRehashPutImpl(enlarge) {.dirty.} = if mustRehash(t.dataLen, t.counter): enlarge(t) index = rawGetKnownHC(t, key, hc) @@ -87,13 +87,13 @@ template maybeRehashPutImpl(enlarge) {.dirty, immediate.} = rawInsert(t, t.data, key, val, hc, index) inc(t.counter) -template putImpl(enlarge) {.dirty, immediate.} = +template putImpl(enlarge) {.dirty.} = var hc: Hash var index = rawGet(t, key, hc) if index >= 0: t.data[index].val = val else: maybeRehashPutImpl(enlarge) -template mgetOrPutImpl(enlarge) {.dirty, immediate.} = +template mgetOrPutImpl(enlarge) {.dirty.} = var hc: Hash var index = rawGet(t, key, hc) if index < 0: @@ -102,7 +102,7 @@ template mgetOrPutImpl(enlarge) {.dirty, immediate.} = # either way return modifiable val result = t.data[index].val -template hasKeyOrPutImpl(enlarge) {.dirty, immediate.} = +template hasKeyOrPutImpl(enlarge) {.dirty.} = var hc: Hash var index = rawGet(t, key, hc) if index < 0: @@ -112,7 +112,7 @@ template hasKeyOrPutImpl(enlarge) {.dirty, immediate.} = proc default[T](t: typedesc[T]): T {.inline.} = discard -template delImpl() {.dirty, immediate.} = +template delImpl() {.dirty.} = var hc: Hash var i = rawGet(t, key, hc) let msk = maxHash(t) @@ -140,7 +140,7 @@ template delImpl() {.dirty, immediate.} = else: shallowCopy(t.data[j], t.data[i]) # data[j] will be marked EMPTY next loop -template clearImpl() {.dirty, immediate.} = +template clearImpl() {.dirty.} = for i in 0 .. = 0: var nxt = t.data[h].next @@ -649,7 +649,7 @@ proc len*[A, B](t: OrderedTableRef[A, B]): int {.inline.} = ## returns the number of keys in `t`. result = t.counter -template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} = +template forAllOrderedPairs(yieldStmt: untyped) {.dirty.} = var h = t.first while h >= 0: var nxt = t.data[h].next @@ -824,7 +824,7 @@ proc rawGet[A](t: CountTable[A], key: A): int = h = nextTry(h, high(t.data)) result = -1 - h # < 0 => MISSING; insert idx = -1 - result -template ctget(t, key: untyped): untyped {.immediate.} = +template ctget(t, key: untyped): untyped = var index = rawGet(t, key) if index >= 0: result = t.data[index].val else: diff --git a/lib/pure/future.nim b/lib/pure/future.nim index 4e2c1d893..67975cfcb 100644 --- a/lib/pure/future.nim +++ b/lib/pure/future.nim @@ -46,7 +46,7 @@ proc createProcType(p, b: NimNode): NimNode {.compileTime.} = #echo(treeRepr(result)) #echo(result.toStrLit()) -macro `=>`*(p, b: expr): expr {.immediate.} = +macro `=>`*(p, b: untyped): untyped = ## Syntax sugar for anonymous procedures. ## ## .. code-block:: nim @@ -107,7 +107,7 @@ macro `=>`*(p, b: expr): expr {.immediate.} = #echo(result.toStrLit()) #return result # TODO: Bug? -macro `->`*(p, b: expr): expr {.immediate.} = +macro `->`*(p, b: untyped): untyped = ## Syntax sugar for procedure types. ## ## .. code-block:: nim @@ -125,7 +125,7 @@ macro `->`*(p, b: expr): expr {.immediate.} = type ListComprehension = object var lc*: ListComprehension -macro `[]`*(lc: ListComprehension, comp, typ: expr): expr = +macro `[]`*(lc: ListComprehension, comp, typ: untyped): untyped = ## List comprehension, returns a sequence. `comp` is the actual list ## comprehension, for example ``x | (x <- 1..10, x mod 2 == 0)``. `typ` is ## the type that will be stored inside the result seq. diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 7898883cf..9501f6dc7 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -1000,11 +1000,11 @@ proc readLine*(socket: Socket, line: var TaintedString, timeout = -1, ## ## **Warning**: Only the ``SafeDisconn`` flag is currently supported. - template addNLIfEmpty(): stmt = + template addNLIfEmpty() = if line.len == 0: line.string.add("\c\L") - template raiseSockError(): stmt {.dirty, immediate.} = + template raiseSockError() {.dirty.} = let lastError = getSocketError(socket) if flags.isDisconnectionError(lastError): setLen(line.string, 0); return socket.socketError(n, lastError = lastError) diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 9eb4cf57d..65bbab3d4 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -173,24 +173,24 @@ proc osLastError*(): OSErrorCode = when defined(windows): when useWinUnicode: - template wrapUnary(varname, winApiProc, arg: expr) {.immediate.} = + template wrapUnary(varname, winApiProc, arg: untyped) = var varname = winApiProc(newWideCString(arg)) - template wrapBinary(varname, winApiProc, arg, arg2: expr) {.immediate.} = + template wrapBinary(varname, winApiProc, arg, arg2: untyped) = var varname = winApiProc(newWideCString(arg), arg2) proc findFirstFile(a: string, b: var WIN32_FIND_DATA): Handle = result = findFirstFileW(newWideCString(a), b) - template findNextFile(a, b: expr): expr = findNextFileW(a, b) - template getCommandLine(): expr = getCommandLineW() + template findNextFile(a, b: untyped): untyped = findNextFileW(a, b) + template getCommandLine(): untyped = getCommandLineW() - template getFilename(f: expr): expr = + template getFilename(f: untyped): untyped = $cast[WideCString](addr(f.cFilename[0])) else: - template findFirstFile(a, b: expr): expr = findFirstFileA(a, b) - template findNextFile(a, b: expr): expr = findNextFileA(a, b) - template getCommandLine(): expr = getCommandLineA() + template findFirstFile(a, b: untyped): untyped = findFirstFileA(a, b) + template findNextFile(a, b: untyped): untyped = findNextFileA(a, b) + template getCommandLine(): untyped = getCommandLineA() - template getFilename(f: expr): expr = $f.cFilename + template getFilename(f: untyped): untyped = $f.cFilename proc skipFindData(f: WIN32_FIND_DATA): bool {.inline.} = # Note - takes advantage of null delimiter in the cstring diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 9b6cf45c5..bfc32bc71 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -475,7 +475,7 @@ proc isNilOrWhitespace*(s: string): bool {.noSideEffect, procvar, rtl, extern: " result = true for c in s: - if not c.isSpace(): + if not c.isSpaceAscii(): return false proc substrEq(s: string, pos: int, substr: string): bool = diff --git a/lib/pure/times.nim b/lib/pure/times.nim index d6cb5c9da..d6eb29e1c 100644 --- a/lib/pure/times.nim +++ b/lib/pure/times.nim @@ -998,21 +998,14 @@ proc parseToken(info: var TimeInfo; token, value: string; j: var int) = info.monthday = value[j..j+1].parseInt() j += 2 of "ddd": - case value[j..j+2].toLower() - of "sun": - info.weekday = dSun - of "mon": - info.weekday = dMon - of "tue": - info.weekday = dTue - of "wed": - info.weekday = dWed - of "thu": - info.weekday = dThu - of "fri": - info.weekday = dFri - of "sat": - info.weekday = dSat + case value[j..j+2].toLowerAscii() + of "sun": info.weekday = dSun + of "mon": info.weekday = dMon + of "tue": info.weekday = dTue + of "wed": info.weekday = dWed + of "thu": info.weekday = dThu + of "fri": info.weekday = dFri + of "sat": info.weekday = dSat else: raise newException(ValueError, "Couldn't parse day of week (ddd), got: " & value[j..j+2]) @@ -1066,31 +1059,19 @@ proc parseToken(info: var TimeInfo; token, value: string; j: var int) = j += 2 info.month = Month(month-1) of "MMM": - case value[j..j+2].toLower(): - of "jan": - info.month = mJan - of "feb": - info.month = mFeb - of "mar": - info.month = mMar - of "apr": - info.month = mApr - of "may": - info.month = mMay - of "jun": - info.month = mJun - of "jul": - info.month = mJul - of "aug": - info.month = mAug - of "sep": - info.month = mSep - of "oct": - info.month = mOct - of "nov": - info.month = mNov - of "dec": - info.month = mDec + case value[j..j+2].toLowerAscii(): + of "jan": info.month = mJan + of "feb": info.month = mFeb + of "mar": info.month = mMar + of "apr": info.month = mApr + of "may": info.month = mMay + of "jun": info.month = mJun + of "jul": info.month = mJul + of "aug": info.month = mAug + of "sep": info.month = mSep + of "oct": info.month = mOct + of "nov": info.month = mNov + of "dec": info.month = mDec else: raise newException(ValueError, "Couldn't parse month (MMM), got: " & value) @@ -1187,7 +1168,7 @@ proc parseToken(info: var TimeInfo; token, value: string; j: var int) = "Couldn't parse timezone offset (zzz), got: " & value[j]) j += 6 of "ZZZ": - info.tzname = value[j..j+2].toUpper() + info.tzname = value[j..j+2].toUpperAscii() j += 3 else: # Ignore the token and move forward in the value string by the same length diff --git a/lib/pure/unittest.nim b/lib/pure/unittest.nim index 7e3983a0d..92ddc3e75 100644 --- a/lib/pure/unittest.nim +++ b/lib/pure/unittest.nim @@ -77,7 +77,7 @@ checkpoints = @[] proc shouldRun(testName: string): bool = result = true -template suite*(name: expr, body: stmt): stmt {.immediate, dirty.} = +template suite*(name, body) {.dirty.} = ## Declare a test suite identified by `name` with optional ``setup`` ## and/or ``teardown`` section. ## @@ -106,13 +106,13 @@ template suite*(name: expr, body: stmt): stmt {.immediate, dirty.} = ## [OK] 2 + 2 = 4 ## [OK] (2 + -2) != 4 block: - template setup(setupBody: stmt): stmt {.immediate, dirty.} = + template setup(setupBody: untyped) {.dirty.} = var testSetupIMPLFlag = true - template testSetupIMPL: stmt {.immediate, dirty.} = setupBody + template testSetupIMPL: untyped {.dirty.} = setupBody - template teardown(teardownBody: stmt): stmt {.immediate, dirty.} = + template teardown(teardownBody: untyped) {.dirty.} = var testTeardownIMPLFlag = true - template testTeardownIMPL: stmt {.immediate, dirty.} = teardownBody + template testTeardownIMPL: untyped {.dirty.} = teardownBody body @@ -135,7 +135,7 @@ proc testDone(name: string, s: TestStatus) = else: rawPrint() -template test*(name: expr, body: stmt): stmt {.immediate, dirty.} = +template test*(name, body) {.dirty.} = ## Define a single test case identified by `name`. ## ## .. code-block:: nim @@ -226,7 +226,7 @@ template skip* = testStatusIMPL = SKIPPED checkpoints = @[] -macro check*(conditions: stmt): stmt {.immediate.} = +macro check*(conditions: untyped): untyped = ## Verify if a statement or a list of statements is true. ## A helpful error message and set checkpoints are printed out on ## failure (if ``outputLevel`` is not ``PRINT_NONE``). @@ -318,7 +318,7 @@ macro check*(conditions: stmt): stmt {.immediate.} = result = getAst(rewrite(checked, checked.lineinfo, checked.toStrLit)) -template require*(conditions: stmt): stmt {.immediate.} = +template require*(conditions: untyped) = ## Same as `check` except any failed test causes the program to quit ## immediately. Any teardown statements are not executed and the failed ## test output is not generated. @@ -328,7 +328,7 @@ template require*(conditions: stmt): stmt {.immediate.} = check conditions abortOnError = savedAbortOnError -macro expect*(exceptions: varargs[expr], body: stmt): stmt {.immediate.} = +macro expect*(exceptions: varargs[typed], body: untyped): untyped = ## Test if `body` raises an exception found in the passed `exceptions`. ## The test passes if the raised exception is part of the acceptable ## exceptions. Otherwise, it fails. diff --git a/lib/system.nim b/lib/system.nim index b4919db2d..2b19b5633 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -338,15 +338,15 @@ proc `<` *[T](x, y: ref T): bool {.magic: "LtPtr", noSideEffect.} proc `<` *[T](x, y: ptr T): bool {.magic: "LtPtr", noSideEffect.} proc `<` *(x, y: pointer): bool {.magic: "LtPtr", noSideEffect.} -template `!=` * (x, y: expr): expr {.immediate.} = +template `!=` * (x, y: untyped): untyped = ## unequals operator. This is a shorthand for ``not (x == y)``. not (x == y) -template `>=` * (x, y: expr): expr {.immediate.} = +template `>=` * (x, y: untyped): untyped = ## "is greater or equals" operator. This is the same as ``y <= x``. y <= x -template `>` * (x, y: expr): expr {.immediate.} = +template `>` * (x, y: untyped): untyped = ## "is greater" operator. This is the same as ``y < x``. y < x @@ -1098,13 +1098,13 @@ proc contains*[T](s: Slice[T], value: T): bool {.noSideEffect, inline.} = ## assert((1..3).contains(4) == false) result = s.a <= value and value <= s.b -template `in` * (x, y: expr): expr {.immediate, dirty.} = contains(y, x) +template `in` * (x, y: untyped): untyped {.dirty.} = contains(y, x) ## Sugar for contains ## ## .. code-block:: Nim ## assert(1 in (1..3) == true) ## assert(5 in (1..3) == false) -template `notin` * (x, y: expr): expr {.immediate, dirty.} = not contains(y, x) +template `notin` * (x, y: untyped): untyped {.dirty.} = not contains(y, x) ## Sugar for not containing ## ## .. code-block:: Nim @@ -1123,7 +1123,7 @@ proc `is` *[T, S](x: T, y: S): bool {.magic: "Is", noSideEffect.} ## ## assert(test[int](3) == 3) ## assert(test[string]("xyz") == 0) -template `isnot` *(x, y: expr): expr {.immediate.} = not (x is y) +template `isnot` *(x, y: untyped): untyped = not (x is y) ## Negated version of `is`. Equivalent to ``not(x is y)``. proc `of` *[T, S](x: T, y: S): bool {.magic: "Of", noSideEffect.} @@ -1742,11 +1742,11 @@ proc swap*[T](a, b: var T) {.magic: "Swap", noSideEffect.} ## swaps the values `a` and `b`. This is often more efficient than ## ``tmp = a; a = b; b = tmp``. Particularly useful for sorting algorithms. -template `>=%` *(x, y: expr): expr {.immediate.} = y <=% x +template `>=%` *(x, y: untyped): untyped = y <=% x ## treats `x` and `y` as unsigned and compares them. ## Returns true iff ``unsigned(x) >= unsigned(y)``. -template `>%` *(x, y: expr): expr {.immediate.} = y <% x +template `>%` *(x, y: untyped): untyped = y <% x ## treats `x` and `y` as unsigned and compares them. ## Returns true iff ``unsigned(x) > unsigned(y)``. @@ -1874,7 +1874,7 @@ iterator countdown*[T](a, b: T, step = 1): T {.inline.} = yield res dec(res, step) -template countupImpl(incr: stmt) {.immediate, dirty.} = +template countupImpl(incr: untyped) {.dirty.} = when T is IntLikeForCount: var res = int(a) while res <= int(b): @@ -3181,7 +3181,7 @@ proc `/`*(x, y: int): float {.inline, noSideEffect.} = ## integer division that results in a float. result = toFloat(x) / toFloat(y) -template spliceImpl(s, a, L, b: expr): stmt {.immediate.} = +template spliceImpl(s, a, L, b: untyped): untyped = # make room for additional elements or cut: var slen = s.len var shift = b.len - L @@ -3467,7 +3467,7 @@ iterator mitems*(a: var string): var char {.inline.} = when not defined(nimhygiene): {.pragma: inject.} -template onFailedAssert*(msg: expr, code: stmt): stmt {.dirty, immediate.} = +template onFailedAssert*(msg, code: untyped): untyped {.dirty.} = ## Sets an assertion failure handler that will intercept any assert ## statements following `onFailedAssert` in the current module scope. ## @@ -3480,7 +3480,7 @@ template onFailedAssert*(msg: expr, code: stmt): stmt {.dirty, immediate.} = ## e.lineinfo = instantiationInfo(-2) ## raise e ## - template failedAssertImpl(msgIMPL: string): stmt {.dirty.} = + template failedAssertImpl(msgIMPL: string): untyped {.dirty.} = let msg = msgIMPL code @@ -3643,7 +3643,7 @@ proc `==` *(x, y: cstring): bool {.magic: "EqCString", noSideEffect, elif x.isNil or y.isNil: result = false else: result = strcmp(x, y) == 0 -template closureScope*(body: untyped): stmt = +template closureScope*(body: untyped): untyped = ## Useful when creating a closure in a loop to capture local loop variables by ## their current iteration values. Example: ## diff --git a/tests/macros/tdumptree.nim b/tests/macros/tdumptree.nim index e5160b7ba..58b011b45 100644 --- a/tests/macros/tdumptree.nim +++ b/tests/macros/tdumptree.nim @@ -3,7 +3,7 @@ msg: '''StmtList VarSection IdentDefs Ident !"x" - nil + Empty Call DotExpr Ident !"foo" diff --git a/todo.txt b/todo.txt index 235d79b78..38d0fef58 100644 --- a/todo.txt +++ b/todo.txt @@ -1,7 +1,9 @@ version 1.0 battle plan ======================= -- Deprecate ``immediate`` for templates and macros +- tests/stdlib/tnre.nim +- tests/closure/tflatmap.nim + - fix "high priority" bugs - try to fix as many compiler crashes as reasonable diff --git a/web/news/version_0_15_released.rst b/web/news/version_0_15_released.rst index e16bdc9ae..c440161c4 100644 --- a/web/news/version_0_15_released.rst +++ b/web/news/version_0_15_released.rst @@ -30,6 +30,10 @@ Changes affecting backwards compatibility discussion. - Overloading the special operators ``.``, ``.()``, ``.=``, ``()`` now should be enabled via ``{.experimental.}``. +- ``immediate`` templates and macros are now deprecated. + Instead use ``untyped`` parameters. +- The metatype ``expr`` is deprecated. Use ``untyped`` instead. +- The metatype ``stmt`` is deprecated. Use ``typed`` instead. Library Additions -- cgit 1.4.1-2-gfad0