stdlib and compiler don't use .immediate anymore

This commit is contained in:
Andreas Rumpf
2016-07-29 17:35:51 +02:00
parent 9ee5b5eabc
commit 60b187513e
36 changed files with 169 additions and 172 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 =

View File

@@ -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

View File

@@ -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)

View File

@@ -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}:

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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())

View File

@@ -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

View File

@@ -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

View File

@@ -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.. <sym.typ.len:
@@ -1623,4 +1623,3 @@ proc evalMacroCall*(module: PSym, n, nOrig: PNode, sym: PSym): PNode =
if cyclicTree(result): globalError(n.info, errCyclicTree)
dec(evalMacroCounter)
c.callsite = nil
#debug result

View File

@@ -230,10 +230,10 @@ const
slotSomeTemp* = slotTempUnknown
relativeJumps* = {opcTJmp, opcFJmp, opcJmp, opcJmpBack}
template opcode*(x: TInstr): TOpcode {.immediate.} = TOpcode(x.uint32 and 0xff'u32)
template regA*(x: TInstr): TRegister {.immediate.} = TRegister(x.uint32 shr 8'u32 and 0xff'u32)
template regB*(x: TInstr): TRegister {.immediate.} = TRegister(x.uint32 shr 16'u32 and 0xff'u32)
template regC*(x: TInstr): TRegister {.immediate.} = TRegister(x.uint32 shr 24'u32)
template regBx*(x: TInstr): int {.immediate.} = (x.uint32 shr 16'u32).int
template opcode*(x: TInstr): TOpcode = TOpcode(x.uint32 and 0xff'u32)
template regA*(x: TInstr): TRegister = TRegister(x.uint32 shr 8'u32 and 0xff'u32)
template regB*(x: TInstr): TRegister = TRegister(x.uint32 shr 16'u32 and 0xff'u32)
template regC*(x: TInstr): TRegister = TRegister(x.uint32 shr 24'u32)
template regBx*(x: TInstr): int = (x.uint32 shr 16'u32).int
template jmpDiff*(x: TInstr): int {.immediate.} = regBx(x) - wordExcess
template jmpDiff*(x: TInstr): int = regBx(x) - wordExcess

View File

@@ -231,7 +231,7 @@ proc getTempRange(cc: PCtx; n: int; kind: TSlotKind): TRegister =
proc freeTempRange(c: PCtx; start: TRegister, n: int) =
for i in start .. start+n-1: c.freeTemp(TRegister(i))
template withTemp(tmp, typ: expr, body: stmt) {.immediate, dirty.} =
template withTemp(tmp, typ, body: untyped) {.dirty.} =
var tmp = getTemp(c, typ)
body
c.freeTemp(tmp)
@@ -241,7 +241,7 @@ proc popBlock(c: PCtx; oldLen: int) =
c.patch(f)
c.prc.blocks.setLen(oldLen)
template withBlock(labl: PSym; body: stmt) {.immediate, dirty.} =
template withBlock(labl: PSym; body: untyped) {.dirty.} =
var oldLen {.gensym.} = c.prc.blocks.len
c.prc.blocks.add TBlock(label: labl, fixups: @[])
body

View File

@@ -7,7 +7,7 @@
# distribution, for details about the copyright.
#
template setX(k, field) {.immediate, dirty.} =
template setX(k, field) {.dirty.} =
var s: seq[TFullReg]
move(s, cast[seq[TFullReg]](a.slots))
if s[a.ra].kind != k:
@@ -48,7 +48,7 @@ proc setResult*(a: VmArgs; v: seq[string]) =
for x in v: n.add newStrNode(nkStrLit, x)
s[a.ra].node = n
template getX(k, field) {.immediate, dirty.} =
template getX(k, field) {.dirty.} =
doAssert i < a.rc-1
let s = cast[seq[TFullReg]](a.slots)
doAssert s[i+a.rb+1].kind == k

View File

@@ -15,36 +15,36 @@ from math import sqrt, ln, log10, log2, exp, round, arccos, arcsin,
from os import getEnv, existsEnv, dirExists, fileExists, walkDir
template mathop(op) {.immediate, dirty.} =
template mathop(op) {.dirty.} =
registerCallback(c, "stdlib.math." & astToStr(op), `op Wrapper`)
template osop(op) {.immediate, dirty.} =
template osop(op) {.dirty.} =
registerCallback(c, "stdlib.os." & astToStr(op), `op Wrapper`)
template systemop(op) {.immediate, dirty.} =
template systemop(op) {.dirty.} =
registerCallback(c, "stdlib.system." & astToStr(op), `op Wrapper`)
template wrap1f_math(op) {.immediate, dirty.} =
template wrap1f_math(op) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op(getFloat(a, 0)))
mathop op
template wrap2f_math(op) {.immediate, dirty.} =
template wrap2f_math(op) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op(getFloat(a, 0), getFloat(a, 1)))
mathop op
template wrap1s_os(op) {.immediate, dirty.} =
template wrap1s_os(op) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op(getString(a, 0)))
osop op
template wrap1s_system(op) {.immediate, dirty.} =
template wrap1s_system(op) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op(getString(a, 0)))
systemop op
template wrap2svoid_system(op) {.immediate, dirty.} =
template wrap2svoid_system(op) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} =
op(getString(a, 0), getString(a, 1))
systemop op

View File

@@ -508,7 +508,7 @@ proc lispRepr*(n: NimNode): string {.compileTime, benign.} =
add(result, ")")
macro dumpTree*(s: stmt): stmt {.immediate.} = echo s.treeRepr
macro dumpTree*(s: untyped): untyped = echo s.treeRepr
## Accepts a block of nim code and prints the parsed abstract syntax
## tree using the `toTree` function. Printing is done *at compile time*.
##
@@ -516,17 +516,17 @@ macro dumpTree*(s: stmt): stmt {.immediate.} = echo s.treeRepr
## tree and to discover what kind of nodes must be created to represent
## a certain expression/statement.
macro dumpLisp*(s: stmt): stmt {.immediate.} = echo s.lispRepr
macro dumpLisp*(s: untyped): untyped = echo s.lispRepr
## Accepts a block of nim code and prints the parsed abstract syntax
## tree using the `toLisp` function. Printing is done *at compile time*.
##
## See `dumpTree`.
macro dumpTreeImm*(s: stmt): stmt {.immediate, deprecated.} = echo s.treeRepr
## The ``immediate`` version of `dumpTree`.
macro dumpTreeImm*(s: untyped): untyped {.deprecated.} = echo s.treeRepr
## Deprecated.
macro dumpLispImm*(s: stmt): stmt {.immediate, deprecated.} = echo s.lispRepr
## The ``immediate`` version of `dumpLisp`.
macro dumpLispImm*(s: untyped): untyped {.deprecated.} = echo s.lispRepr
## Deprecated.
proc newEmptyNode*(): NimNode {.compileTime, noSideEffect.} =
@@ -701,7 +701,7 @@ proc addPragma*(someProc, pragma: NimNode) {.compileTime.} =
someProc.pragma = pragmaNode
pragmaNode.add(pragma)
template badNodeKind(k; f): stmt{.immediate.} =
template badNodeKind(k, f) =
assert false, "Invalid node kind " & $k & " for macros.`" & $f & "`"
proc body*(someProc: NimNode): NimNode {.compileTime.} =
@@ -758,8 +758,7 @@ iterator children*(n: NimNode): NimNode {.inline.} =
for i in 0 ..< n.len:
yield n[i]
template findChild*(n: NimNode; cond: expr): NimNode {.
immediate, dirty.} =
template findChild*(n: NimNode; cond: untyped): NimNode {.dirty.} =
## Find the first child node matching condition (or nil).
##
## .. code-block:: nim

View File

@@ -274,7 +274,7 @@ proc `[]`*(pattern: Captures, name: string): string =
let pattern = RegexMatch(pattern)
return pattern.captures[pattern.pattern.captureNameToId.fget(name)]
template toTableImpl(cond: bool): stmt {.immediate, dirty.} =
template toTableImpl(cond: untyped) {.dirty.} =
for key in RegexMatch(pattern).pattern.captureNameId.keys:
let nextVal = pattern[key]
if cond:
@@ -291,7 +291,7 @@ proc toTable*(pattern: CaptureBounds, default = none(Slice[int])):
result = initTable[string, Option[Slice[int]]]()
toTableImpl(nextVal.isNone)
template itemsImpl(cond: bool): stmt {.immediate, dirty.} =
template itemsImpl(cond: untyped) {.dirty.} =
for i in 0 .. <RegexMatch(pattern).pattern.captureCount:
let nextVal = pattern[i]
# done in this roundabout way to avoid multiple yields (potential code
@@ -625,7 +625,7 @@ proc split*(str: string, pattern: Regex, maxSplit = -1, start = 0): seq[string]
result.add(str.substr(bounds.b + 1, str.high))
template replaceImpl(str: string, pattern: Regex,
replacement: expr): stmt {.immediate, dirty.} =
replacement: untyped) {.dirty.} =
# XXX seems very similar to split, maybe I can reduce code duplication
# somehow?
result = ""

View File

@@ -983,7 +983,7 @@ when defined(windows) or defined(nimdoc):
let dwLocalAddressLength = Dword(sizeof (Sockaddr_in) + 16)
let dwRemoteAddressLength = Dword(sizeof(Sockaddr_in) + 16)
template completeAccept(): stmt {.immediate, dirty.} =
template completeAccept() {.dirty.} =
var listenSock = socket
let setoptRet = setsockopt(clientSock, SOL_SOCKET,
SO_UPDATE_ACCEPT_CONTEXT, addr listenSock,
@@ -1003,7 +1003,7 @@ when defined(windows) or defined(nimdoc):
client: clientSock.AsyncFD)
)
template failAccept(errcode): stmt =
template failAccept(errcode) =
if flags.isDisconnectionError(errcode):
var newAcceptFut = acceptAddr(socket, flags)
newAcceptFut.callback =
@@ -1590,7 +1590,7 @@ proc skipStmtList(node: NimNode): NimNode {.compileTime.} =
result = node[0]
template createCb(retFutureSym, iteratorNameSym,
name: expr): stmt {.immediate.} =
name: untyped) =
var nameIterVar = iteratorNameSym
#{.push stackTrace: off.}
proc cb {.closure,gcsafe.} =
@@ -1925,7 +1925,7 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
#if prc[0].getName == "testInfix":
# echo(toStrLit(result))
macro async*(prc: stmt): stmt {.immediate.} =
macro async*(prc: untyped): untyped =
## Macro which processes async procedures into the appropriate
## iterators and yield statements.
if prc.kind == nnkStmtList:

View File

@@ -355,7 +355,7 @@ proc insert*[T](dest: var seq[T], src: openArray[T], pos=0) =
inc(j)
template filterIt*(seq1, pred: expr): expr =
template filterIt*(seq1, pred: untyped): untyped =
## Returns a new sequence with all the items that fulfilled the predicate.
##
## Unlike the `proc` version, the predicate needs to be an expression using
@@ -374,7 +374,7 @@ template filterIt*(seq1, pred: expr): expr =
if pred: result.add(it)
result
template keepItIf*(varSeq: seq, pred: expr) =
template keepItIf*(varSeq: seq, pred: untyped) =
## Convenience template around the ``keepIf`` proc to reduce typing.
##
## Unlike the `proc` version, the predicate needs to be an expression using
@@ -409,7 +409,7 @@ proc all*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): bool =
return false
return true
template allIt*(seq1, pred: expr): bool {.immediate.} =
template allIt*(seq1, pred: untyped): bool =
## Checks if every item fulfills the predicate.
##
## Example:
@@ -440,7 +440,7 @@ proc any*[T](seq1: seq[T], pred: proc(item: T): bool {.closure.}): bool =
return true
return false
template anyIt*(seq1, pred: expr): bool {.immediate.} =
template anyIt*(seq1, pred: untyped): bool =
## Checks if some item fulfills the predicate.
##
## Example:
@@ -456,7 +456,7 @@ template anyIt*(seq1, pred: expr): bool {.immediate.} =
break
result
template toSeq*(iter: expr): expr {.immediate.} =
template toSeq*(iter: untyped): untyped =
## Transforms any iterator into a sequence.
##
## Example:
@@ -482,7 +482,7 @@ template toSeq*(iter: expr): expr {.immediate.} =
result.add(x)
result
template foldl*(sequence, operation: expr): expr =
template foldl*(sequence, operation: untyped): untyped =
## Template to fold a sequence from left to right, returning the accumulation.
##
## The sequence is required to have at least a single element. Debug versions
@@ -519,7 +519,7 @@ template foldl*(sequence, operation: expr): expr =
result = operation
result
template foldl*(sequence, operation: expr, first): expr =
template foldl*(sequence, operation, first): untyped =
## Template to fold a sequence from left to right, returning the accumulation.
##
## This version of ``foldl`` gets a starting parameter. This makes it possible
@@ -544,7 +544,7 @@ template foldl*(sequence, operation: expr, first): expr =
result = operation
result
template foldr*(sequence, operation: expr): expr =
template foldr*(sequence, operation: untyped): untyped =
## Template to fold a sequence from right to left, returning the accumulation.
##
## The sequence is required to have at least a single element. Debug versions
@@ -581,7 +581,7 @@ template foldr*(sequence, operation: expr): expr =
result = operation
result
template mapIt*(seq1, typ, op: expr): expr {.deprecated.}=
template mapIt*(seq1, typ, op: untyped): untyped =
## Convenience template around the ``map`` proc to reduce typing.
##
## The template injects the ``it`` variable which you can use directly in an
@@ -602,7 +602,7 @@ template mapIt*(seq1, typ, op: expr): expr {.deprecated.}=
result
template mapIt*(seq1, op: expr): expr =
template mapIt*(seq1, op: untyped): untyped =
## Convenience template around the ``map`` proc to reduce typing.
##
## The template injects the ``it`` variable which you can use directly in an
@@ -631,7 +631,7 @@ template mapIt*(seq1, op: expr): expr =
result.add(op)
result
template applyIt*(varSeq, op: expr) =
template applyIt*(varSeq, op: untyped) =
## Convenience template around the mutable ``apply`` proc to reduce typing.
##
## The template injects the ``it`` variable which you can use directly in an
@@ -648,7 +648,7 @@ template applyIt*(varSeq, op: expr) =
template newSeqWith*(len: int, init: expr): expr =
template newSeqWith*(len: int, init: untyped): untyped =
## creates a new sequence, calling `init` to initialize each value. Example:
##
## .. code-block::

View File

@@ -286,7 +286,7 @@ proc excl*[A](s: var HashSet[A], key: A) =
var r = j # though may be adaptable to other simple sequences.
s.data[i].hcode = 0 # mark current EMPTY
s.data[i].key = default(type(s.data[i].key))
doWhile ((i >= 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.} =
## <http://en.wikipedia.org/wiki/Cardinality>`_ 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

View File

@@ -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 .. <t.data.len:
t.data[i].hcode = 0
t.data[i].key = default(type(t.data[i].key))

View File

@@ -113,8 +113,8 @@ type
{.deprecated: [TTable: Table, PTable: TableRef].}
template maxHash(t): expr {.immediate.} = high(t.data)
template dataLen(t): expr = len(t.data)
template maxHash(t): untyped = high(t.data)
template dataLen(t): untyped = len(t.data)
include tableimpl
@@ -135,7 +135,7 @@ proc len*[A, B](t: Table[A, B]): int =
## returns the number of keys in `t`.
result = t.counter
template get(t, key): untyped {.immediate.} =
template get(t, key): untyped =
## retrieves the value at ``t[key]``. The value can be modified.
## If `key` is not in `t`, the ``KeyError`` exception is raised.
mixin rawGet
@@ -148,7 +148,7 @@ template get(t, key): untyped {.immediate.} =
else:
raise newException(KeyError, "key not found")
template getOrDefaultImpl(t, key): untyped {.immediate.} =
template getOrDefaultImpl(t, key): untyped =
mixin rawGet
var hc: Hash
var index = rawGet(t, key, hc)
@@ -311,7 +311,7 @@ proc toTable*[A, B](pairs: openArray[(A,
result = initTable[A, B](rightSize(pairs.len))
for key, val in items(pairs): result[key] = val
template dollarImpl(): stmt {.dirty.} =
template dollarImpl(): untyped {.dirty.} =
if t.len == 0:
result = "{:}"
else:
@@ -463,7 +463,7 @@ proc clear*[A, B](t: OrderedTable[A, B] | OrderedTableRef[A, B]) =
t.first = -1
t.last = -1
template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} =
template forAllOrderedPairs(yieldStmt: untyped) {.dirty.} =
var h = t.first
while h >= 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:

View File

@@ -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.

View File

@@ -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)

View File

@@ -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

View File

@@ -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 =

View File

@@ -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

View File

@@ -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.

View File

@@ -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:
##

View File

@@ -3,7 +3,7 @@ msg: '''StmtList
VarSection
IdentDefs
Ident !"x"
nil
Empty
Call
DotExpr
Ident !"foo"

View File

@@ -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

View File

@@ -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