stdlib and compiler don't use .immediate anymore

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

View file

@ -278,6 +278,8 @@ const
sfImmediate* = sfDeadCodeElim sfImmediate* = sfDeadCodeElim
# macro or template is immediately expanded # macro or template is immediately expanded
# without considering any possible overloads # without considering any possible overloads
sfAllUntyped* = sfVolatile # macro or template is immediately expanded \
# in a generic context
sfDirty* = sfPure sfDirty* = sfPure
# template is not hygienic (old styled template) # template is not hygienic (old styled template)

View file

@ -229,7 +229,7 @@ proc processMergeInfo(L: var TBaseLexer, m: BModule) =
when not defined(nimhygiene): when not defined(nimhygiene):
{.pragma: inject.} {.pragma: inject.}
template withCFile(cfilename: string, body: stmt) {.immediate.} = template withCFile(cfilename: string, body: untyped) =
var s = llStreamOpen(cfilename, fmRead) var s = llStreamOpen(cfilename, fmRead)
if s == nil: return if s == nil: return
var L {.inject.}: TBaseLexer var L {.inject.}: TBaseLexer

View file

@ -136,7 +136,7 @@ proc exprBlock(p: BProc, n: PNode, d: var TLoc) =
expr(p, n, d) expr(p, n, d)
endBlock(p) endBlock(p)
template preserveBreakIdx(body: stmt): stmt {.immediate.} = template preserveBreakIdx(body: untyped): untyped =
var oldBreakIdx = p.breakIdx var oldBreakIdx = p.breakIdx
body body
p.breakIdx = oldBreakIdx p.breakIdx = oldBreakIdx

View file

@ -61,7 +61,7 @@ type
# When adding new compilers, the cmake sources could be a good reference: # When adding new compilers, the cmake sources could be a good reference:
# http://cmake.org/gitweb?p=cmake.git;a=tree;f=Modules/Platform; # 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 proc name: TInfoCC {.compileTime.} = settings
# GNU C and C++ Compiler # GNU C and C++ Compiler

View file

@ -95,7 +95,7 @@ type
up: PProc # up the call chain; required for closure support up: PProc # up the call chain; required for closure support
declaredGlobals: IntSet declaredGlobals: IntSet
template `|`(a, b: expr): expr {.immediate, dirty.} = template `|`(a, b: untyped): untyped {.dirty.} =
(if p.target == targetJS: a else: b) (if p.target == targetJS: a else: b)
proc newGlobals(): PGlobals = 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` ## Produce and emit a parser message to output about the token `tok`
parMessage(p, msg, prettyTok(tok)) parMessage(p, msg, prettyTok(tok))
template withInd(p: expr, body: stmt) {.immediate.} = template withInd(p, body: untyped) =
let oldInd = p.currInd let oldInd = p.currInd
p.currInd = p.tok.indent p.currInd = p.tok.indent
body body

View file

@ -626,7 +626,10 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
processImportCompilerProc(sym, getOptionalStr(c, it, "$1")) processImportCompilerProc(sym, getOptionalStr(c, it, "$1"))
of wExtern: setExternName(sym, expectStrLit(c, it)) of wExtern: setExternName(sym, expectStrLit(c, it))
of wImmediate: 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) else: invalidPragma(it)
of wDirty: of wDirty:
if sym.kind == skTemplate: incl(sym.flags, sfDirty) 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} const ordIntLit = {nkIntLit..nkUInt64Lit}
result = n.typ result = n.typ
template commutativeOp(opr: expr) {.immediate.} = template commutativeOp(opr: untyped) =
let a = n.sons[1] let a = n.sons[1]
let b = n.sons[2] let b = n.sons[2]
if isIntRangeOrLit(a.typ) and isIntRangeOrLit(b.typ): 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(pickMinInt(a), pickMinInt(b)),
opr(pickMaxInt(a), pickMaxInt(b))) opr(pickMaxInt(a), pickMaxInt(b)))
template binaryOp(opr: expr) {.immediate.} = template binaryOp(opr: untyped) =
let a = n.sons[1] let a = n.sons[1]
let b = n.sons[2] let b = n.sons[2]
if isIntRange(a.typ) and b.kind in {nkIntLit..nkUInt64Lit}: if isIntRange(a.typ) and b.kind in {nkIntLit..nkUInt64Lit}:

View file

@ -48,7 +48,10 @@ proc semGenericStmtScope(c: PContext, n: PNode,
closeScope(c) closeScope(c)
template macroToExpand(s: expr): expr = 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, proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
ctx: var GenericCtx): PNode = ctx: var GenericCtx): PNode =
@ -61,14 +64,14 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
of skProc, skMethod, skIterator, skConverter, skModule: of skProc, skMethod, skIterator, skConverter, skModule:
result = symChoice(c, n, s, scOpen) result = symChoice(c, n, s, scOpen)
of skTemplate: of skTemplate:
if macroToExpand(s): if macroToExpandSym(s):
styleCheckUse(n.info, s) styleCheckUse(n.info, s)
result = semTemplateExpr(c, n, s, {efNoSemCheck}) result = semTemplateExpr(c, n, s, {efNoSemCheck})
result = semGenericStmt(c, result, {}, ctx) result = semGenericStmt(c, result, {}, ctx)
else: else:
result = symChoice(c, n, s, scOpen) result = symChoice(c, n, s, scOpen)
of skMacro: of skMacro:
if macroToExpand(s): if macroToExpandSym(s):
styleCheckUse(n.info, s) styleCheckUse(n.info, s)
result = semMacroExpr(c, n, n, s, {efNoSemCheck}) result = semMacroExpr(c, n, n, s, {efNoSemCheck})
result = semGenericStmt(c, result, {}, ctx) 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 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 inc c.spawns
let oldSpawnId = c.currentSpawnId let oldSpawnId = c.currentSpawnId
c.currentSpawnId = c.spawns c.currentSpawnId = c.spawns

View file

@ -577,13 +577,16 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
else: else:
gp = newNodeI(nkGenericParams, n.info) gp = newNodeI(nkGenericParams, n.info)
# process parameters: # process parameters:
var allUntyped = true
if n.sons[paramsPos].kind != nkEmpty: if n.sons[paramsPos].kind != nkEmpty:
semParamList(c, n.sons[paramsPos], gp, s) semParamList(c, n.sons[paramsPos], gp, s)
# a template's parameters are not gensym'ed even if that was originally the # 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 # case as we determine whether it's a template parameter in the template
# body by the absence of the sfGenSym flag: # body by the absence of the sfGenSym flag:
for i in 1 .. s.typ.n.len-1: 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 sonsLen(gp) > 0:
if n.sons[genericParamsPos].kind == nkEmpty: if n.sons[genericParamsPos].kind == nkEmpty:
# we have a list of implicit type parameters: # 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) s.typ.n = newNodeI(nkFormalParams, n.info)
rawAddSon(s.typ, newTypeS(tyStmt, c)) rawAddSon(s.typ, newTypeS(tyStmt, c))
addSon(s.typ.n, newNodeIT(nkType, n.info, s.typ.sons[0])) addSon(s.typ.n, newNodeIT(nkType, n.info, s.typ.sons[0]))
if allUntyped: incl(s.flags, sfAllUntyped)
if n.sons[patternPos].kind != nkEmpty: if n.sons[patternPos].kind != nkEmpty:
n.sons[patternPos] = semPattern(c, n.sons[patternPos]) n.sons[patternPos] = semPattern(c, n.sons[patternPos])
var ctx: TemplCtx var ctx: TemplCtx
@ -629,7 +633,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
proc semPatternBody(c: var TemplCtx, n: PNode): PNode = proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
template templToExpand(s: expr): expr = 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 = proc newParam(c: var TemplCtx, n: PNode, s: PSym): PNode =
# the param added in the current scope is actually wrong here for # 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) put(c.bindings, f, bound)
return res return res
template considerPreviousT(body: stmt) {.immediate.} = template considerPreviousT(body: untyped) =
var prev = PType(idTableGet(c.bindings, f)) var prev = PType(idTableGet(c.bindings, f))
if prev == nil: body if prev == nil: body
else: return typeRel(c, prev, a) else: return typeRel(c, prev, a)
@ -1591,7 +1591,7 @@ template isVarargsUntyped(x): expr =
proc matchesAux(c: PContext, n, nOrig: PNode, proc matchesAux(c: PContext, n, nOrig: PNode,
m: var TCandidate, marker: var IntSet) = m: var TCandidate, marker: var IntSet) =
template checkConstraint(n: expr) {.immediate, dirty.} = template checkConstraint(n: untyped) {.dirty.} =
if not formal.constraint.isNil: if not formal.constraint.isNil:
if matchNodeKinds(formal.constraint, n): if matchNodeKinds(formal.constraint, n):
# better match over other routines with no such restriction: # 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 include suggest
when not declared(tests): when not declared(tests):
template tests(s: stmt) {.immediate.} = discard template tests(s: untyped) = discard
tests: tests:
var dummyOwner = newSym(skModule, getIdent("test_module"), nil, UnknownLineInfo()) 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)) suggestResult(symToSuggest(s, isLocal=true, $ideSug, 100))
inc outputs inc outputs
template wholeSymTab(cond, section: expr) {.immediate.} = template wholeSymTab(cond, section: untyped) =
var isLocal = true var isLocal = true
for scope in walkScopes(c.currentScope): for scope in walkScopes(c.currentScope):
if scope == c.topLevelScope: isLocal = false 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: elif a.n != b.n and (a.n == nil or b.n == nil) and IgnoreTupleFields notin c.flags:
result = false result = false
template ifFastObjectTypeCheckFailed(a, b: PType, body: stmt) {.immediate.} = template ifFastObjectTypeCheckFailed(a, b: PType, body: untyped) =
if tfFromGeneric notin a.flags + b.flags: if tfFromGeneric notin a.flags + b.flags:
# fast case: id comparison suffices: # fast case: id comparison suffices:
result = a.id == b.id result = a.id == b.id

View file

@ -92,34 +92,34 @@ when not defined(nimComputedGoto):
proc myreset(n: var TFullReg) = reset(n) proc myreset(n: var TFullReg) = reset(n)
template ensureKind(k: expr) {.immediate, dirty.} = template ensureKind(k: untyped) {.dirty.} =
if regs[ra].kind != k: if regs[ra].kind != k:
myreset(regs[ra]) myreset(regs[ra])
regs[ra].kind = k regs[ra].kind = k
template decodeB(k: expr) {.immediate, dirty.} = template decodeB(k: untyped) {.dirty.} =
let rb = instr.regB let rb = instr.regB
ensureKind(k) ensureKind(k)
template decodeBC(k: expr) {.immediate, dirty.} = template decodeBC(k: untyped) {.dirty.} =
let rb = instr.regB let rb = instr.regB
let rc = instr.regC let rc = instr.regC
ensureKind(k) ensureKind(k)
template declBC() {.immediate, dirty.} = template declBC() {.dirty.} =
let rb = instr.regB let rb = instr.regB
let rc = instr.regC let rc = instr.regC
template decodeBImm(k: expr) {.immediate, dirty.} = template decodeBImm(k: untyped) {.dirty.} =
let rb = instr.regB let rb = instr.regB
let imm = instr.regC - byteExcess let imm = instr.regC - byteExcess
ensureKind(k) ensureKind(k)
template decodeBx(k: expr) {.immediate, dirty.} = template decodeBx(k: expr) {.dirty.} =
let rbx = instr.regBx - wordExcess let rbx = instr.regBx - wordExcess
ensureKind(k) 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 # XXX fix minor 'shallowCopy' overloading bug in compiler
proc createStrKeepNode(x: var TFullReg; keepNode=true) = proc createStrKeepNode(x: var TFullReg; keepNode=true) =
@ -1573,7 +1573,7 @@ proc setupMacroParam(x: PNode, typ: PType): TFullReg =
var evalMacroCounter: int var evalMacroCounter: int
proc evalMacroCall*(module: PSym, n, nOrig: PNode, sym: PSym): PNode = 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) inc(evalMacroCounter)
if evalMacroCounter > 100: if evalMacroCounter > 100:
globalError(n.info, errTemplateInstantiationTooNested) globalError(n.info, errTemplateInstantiationTooNested)
@ -1603,7 +1603,7 @@ proc evalMacroCall*(module: PSym, n, nOrig: PNode, sym: PSym): PNode =
# return value: # return value:
tos.slots[0].kind = rkNode 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: # setup parameters:
for i in 1.. <sym.typ.len: 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) if cyclicTree(result): globalError(n.info, errCyclicTree)
dec(evalMacroCounter) dec(evalMacroCounter)
c.callsite = nil c.callsite = nil
#debug result

View file

@ -230,10 +230,10 @@ const
slotSomeTemp* = slotTempUnknown slotSomeTemp* = slotTempUnknown
relativeJumps* = {opcTJmp, opcFJmp, opcJmp, opcJmpBack} relativeJumps* = {opcTJmp, opcFJmp, opcJmp, opcJmpBack}
template opcode*(x: TInstr): TOpcode {.immediate.} = TOpcode(x.uint32 and 0xff'u32) template opcode*(x: TInstr): TOpcode = TOpcode(x.uint32 and 0xff'u32)
template regA*(x: TInstr): TRegister {.immediate.} = TRegister(x.uint32 shr 8'u32 and 0xff'u32) template regA*(x: TInstr): TRegister = 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 regB*(x: TInstr): TRegister = TRegister(x.uint32 shr 16'u32 and 0xff'u32)
template regC*(x: TInstr): TRegister {.immediate.} = TRegister(x.uint32 shr 24'u32) template regC*(x: TInstr): TRegister = TRegister(x.uint32 shr 24'u32)
template regBx*(x: TInstr): int {.immediate.} = (x.uint32 shr 16'u32).int 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) = proc freeTempRange(c: PCtx; start: TRegister, n: int) =
for i in start .. start+n-1: c.freeTemp(TRegister(i)) 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) var tmp = getTemp(c, typ)
body body
c.freeTemp(tmp) c.freeTemp(tmp)
@ -241,7 +241,7 @@ proc popBlock(c: PCtx; oldLen: int) =
c.patch(f) c.patch(f)
c.prc.blocks.setLen(oldLen) 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 var oldLen {.gensym.} = c.prc.blocks.len
c.prc.blocks.add TBlock(label: labl, fixups: @[]) c.prc.blocks.add TBlock(label: labl, fixups: @[])
body body

View file

@ -7,7 +7,7 @@
# distribution, for details about the copyright. # distribution, for details about the copyright.
# #
template setX(k, field) {.immediate, dirty.} = template setX(k, field) {.dirty.} =
var s: seq[TFullReg] var s: seq[TFullReg]
move(s, cast[seq[TFullReg]](a.slots)) move(s, cast[seq[TFullReg]](a.slots))
if s[a.ra].kind != k: 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) for x in v: n.add newStrNode(nkStrLit, x)
s[a.ra].node = n s[a.ra].node = n
template getX(k, field) {.immediate, dirty.} = template getX(k, field) {.dirty.} =
doAssert i < a.rc-1 doAssert i < a.rc-1
let s = cast[seq[TFullReg]](a.slots) let s = cast[seq[TFullReg]](a.slots)
doAssert s[i+a.rb+1].kind == k 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 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`) 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`) 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`) 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.} = proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op(getFloat(a, 0))) setResult(a, op(getFloat(a, 0)))
mathop op mathop op
template wrap2f_math(op) {.immediate, dirty.} = template wrap2f_math(op) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} = proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op(getFloat(a, 0), getFloat(a, 1))) setResult(a, op(getFloat(a, 0), getFloat(a, 1)))
mathop op mathop op
template wrap1s_os(op) {.immediate, dirty.} = template wrap1s_os(op) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} = proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op(getString(a, 0))) setResult(a, op(getString(a, 0)))
osop op osop op
template wrap1s_system(op) {.immediate, dirty.} = template wrap1s_system(op) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} = proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op(getString(a, 0))) setResult(a, op(getString(a, 0)))
systemop op systemop op
template wrap2svoid_system(op) {.immediate, dirty.} = template wrap2svoid_system(op) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} = proc `op Wrapper`(a: VmArgs) {.nimcall.} =
op(getString(a, 0), getString(a, 1)) op(getString(a, 0), getString(a, 1))
systemop op systemop op

View file

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

View file

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

View file

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

View file

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

View file

@ -615,7 +615,7 @@ proc card*[A](s: OrderedSet[A]): int {.inline.} =
## <http://en.wikipedia.org/wiki/Cardinality>`_ of a set. ## <http://en.wikipedia.org/wiki/Cardinality>`_ of a set.
result = s.counter result = s.counter
template forAllOrderedPairs(yieldStmt: stmt) {.dirty, immediate.} = template forAllOrderedPairs(yieldStmt: untyped) {.dirty.} =
var h = s.first var h = s.first
while h >= 0: while h >= 0:
var nxt = s.data[h].next 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) = key: A, val: B, hc: Hash, h: Hash) =
rawInsertImpl() rawInsertImpl()
template addImpl(enlarge) {.dirty, immediate.} = template addImpl(enlarge) {.dirty.} =
if mustRehash(t.dataLen, t.counter): enlarge(t) if mustRehash(t.dataLen, t.counter): enlarge(t)
var hc: Hash var hc: Hash
var j = rawGetDeep(t, key, hc) var j = rawGetDeep(t, key, hc)
rawInsert(t, t.data, key, val, hc, j) rawInsert(t, t.data, key, val, hc, j)
inc(t.counter) inc(t.counter)
template maybeRehashPutImpl(enlarge) {.dirty, immediate.} = template maybeRehashPutImpl(enlarge) {.dirty.} =
if mustRehash(t.dataLen, t.counter): if mustRehash(t.dataLen, t.counter):
enlarge(t) enlarge(t)
index = rawGetKnownHC(t, key, hc) index = rawGetKnownHC(t, key, hc)
@ -87,13 +87,13 @@ template maybeRehashPutImpl(enlarge) {.dirty, immediate.} =
rawInsert(t, t.data, key, val, hc, index) rawInsert(t, t.data, key, val, hc, index)
inc(t.counter) inc(t.counter)
template putImpl(enlarge) {.dirty, immediate.} = template putImpl(enlarge) {.dirty.} =
var hc: Hash var hc: Hash
var index = rawGet(t, key, hc) var index = rawGet(t, key, hc)
if index >= 0: t.data[index].val = val if index >= 0: t.data[index].val = val
else: maybeRehashPutImpl(enlarge) else: maybeRehashPutImpl(enlarge)
template mgetOrPutImpl(enlarge) {.dirty, immediate.} = template mgetOrPutImpl(enlarge) {.dirty.} =
var hc: Hash var hc: Hash
var index = rawGet(t, key, hc) var index = rawGet(t, key, hc)
if index < 0: if index < 0:
@ -102,7 +102,7 @@ template mgetOrPutImpl(enlarge) {.dirty, immediate.} =
# either way return modifiable val # either way return modifiable val
result = t.data[index].val result = t.data[index].val
template hasKeyOrPutImpl(enlarge) {.dirty, immediate.} = template hasKeyOrPutImpl(enlarge) {.dirty.} =
var hc: Hash var hc: Hash
var index = rawGet(t, key, hc) var index = rawGet(t, key, hc)
if index < 0: if index < 0:
@ -112,7 +112,7 @@ template hasKeyOrPutImpl(enlarge) {.dirty, immediate.} =
proc default[T](t: typedesc[T]): T {.inline.} = discard proc default[T](t: typedesc[T]): T {.inline.} = discard
template delImpl() {.dirty, immediate.} = template delImpl() {.dirty.} =
var hc: Hash var hc: Hash
var i = rawGet(t, key, hc) var i = rawGet(t, key, hc)
let msk = maxHash(t) let msk = maxHash(t)
@ -140,7 +140,7 @@ template delImpl() {.dirty, immediate.} =
else: else:
shallowCopy(t.data[j], t.data[i]) # data[j] will be marked EMPTY next loop 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: for i in 0 .. <t.data.len:
t.data[i].hcode = 0 t.data[i].hcode = 0
t.data[i].key = default(type(t.data[i].key)) t.data[i].key = default(type(t.data[i].key))

View file

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

View file

@ -46,7 +46,7 @@ proc createProcType(p, b: NimNode): NimNode {.compileTime.} =
#echo(treeRepr(result)) #echo(treeRepr(result))
#echo(result.toStrLit()) #echo(result.toStrLit())
macro `=>`*(p, b: expr): expr {.immediate.} = macro `=>`*(p, b: untyped): untyped =
## Syntax sugar for anonymous procedures. ## Syntax sugar for anonymous procedures.
## ##
## .. code-block:: nim ## .. code-block:: nim
@ -107,7 +107,7 @@ macro `=>`*(p, b: expr): expr {.immediate.} =
#echo(result.toStrLit()) #echo(result.toStrLit())
#return result # TODO: Bug? #return result # TODO: Bug?
macro `->`*(p, b: expr): expr {.immediate.} = macro `->`*(p, b: untyped): untyped =
## Syntax sugar for procedure types. ## Syntax sugar for procedure types.
## ##
## .. code-block:: nim ## .. code-block:: nim
@ -125,7 +125,7 @@ macro `->`*(p, b: expr): expr {.immediate.} =
type ListComprehension = object type ListComprehension = object
var lc*: ListComprehension 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 ## List comprehension, returns a sequence. `comp` is the actual list
## comprehension, for example ``x | (x <- 1..10, x mod 2 == 0)``. `typ` is ## comprehension, for example ``x | (x <- 1..10, x mod 2 == 0)``. `typ` is
## the type that will be stored inside the result seq. ## 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. ## **Warning**: Only the ``SafeDisconn`` flag is currently supported.
template addNLIfEmpty(): stmt = template addNLIfEmpty() =
if line.len == 0: if line.len == 0:
line.string.add("\c\L") line.string.add("\c\L")
template raiseSockError(): stmt {.dirty, immediate.} = template raiseSockError() {.dirty.} =
let lastError = getSocketError(socket) let lastError = getSocketError(socket)
if flags.isDisconnectionError(lastError): setLen(line.string, 0); return if flags.isDisconnectionError(lastError): setLen(line.string, 0); return
socket.socketError(n, lastError = lastError) socket.socketError(n, lastError = lastError)

View file

@ -173,24 +173,24 @@ proc osLastError*(): OSErrorCode =
when defined(windows): when defined(windows):
when useWinUnicode: when useWinUnicode:
template wrapUnary(varname, winApiProc, arg: expr) {.immediate.} = template wrapUnary(varname, winApiProc, arg: untyped) =
var varname = winApiProc(newWideCString(arg)) 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) var varname = winApiProc(newWideCString(arg), arg2)
proc findFirstFile(a: string, b: var WIN32_FIND_DATA): Handle = proc findFirstFile(a: string, b: var WIN32_FIND_DATA): Handle =
result = findFirstFileW(newWideCString(a), b) result = findFirstFileW(newWideCString(a), b)
template findNextFile(a, b: expr): expr = findNextFileW(a, b) template findNextFile(a, b: untyped): untyped = findNextFileW(a, b)
template getCommandLine(): expr = getCommandLineW() template getCommandLine(): untyped = getCommandLineW()
template getFilename(f: expr): expr = template getFilename(f: untyped): untyped =
$cast[WideCString](addr(f.cFilename[0])) $cast[WideCString](addr(f.cFilename[0]))
else: else:
template findFirstFile(a, b: expr): expr = findFirstFileA(a, b) template findFirstFile(a, b: untyped): untyped = findFirstFileA(a, b)
template findNextFile(a, b: expr): expr = findNextFileA(a, b) template findNextFile(a, b: untyped): untyped = findNextFileA(a, b)
template getCommandLine(): expr = getCommandLineA() 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.} = proc skipFindData(f: WIN32_FIND_DATA): bool {.inline.} =
# Note - takes advantage of null delimiter in the cstring # 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 result = true
for c in s: for c in s:
if not c.isSpace(): if not c.isSpaceAscii():
return false return false
proc substrEq(s: string, pos: int, substr: string): bool = 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() info.monthday = value[j..j+1].parseInt()
j += 2 j += 2
of "ddd": of "ddd":
case value[j..j+2].toLower() case value[j..j+2].toLowerAscii()
of "sun": of "sun": info.weekday = dSun
info.weekday = dSun of "mon": info.weekday = dMon
of "mon": of "tue": info.weekday = dTue
info.weekday = dMon of "wed": info.weekday = dWed
of "tue": of "thu": info.weekday = dThu
info.weekday = dTue of "fri": info.weekday = dFri
of "wed": of "sat": info.weekday = dSat
info.weekday = dWed
of "thu":
info.weekday = dThu
of "fri":
info.weekday = dFri
of "sat":
info.weekday = dSat
else: else:
raise newException(ValueError, raise newException(ValueError,
"Couldn't parse day of week (ddd), got: " & value[j..j+2]) "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 j += 2
info.month = Month(month-1) info.month = Month(month-1)
of "MMM": of "MMM":
case value[j..j+2].toLower(): case value[j..j+2].toLowerAscii():
of "jan": of "jan": info.month = mJan
info.month = mJan of "feb": info.month = mFeb
of "feb": of "mar": info.month = mMar
info.month = mFeb of "apr": info.month = mApr
of "mar": of "may": info.month = mMay
info.month = mMar of "jun": info.month = mJun
of "apr": of "jul": info.month = mJul
info.month = mApr of "aug": info.month = mAug
of "may": of "sep": info.month = mSep
info.month = mMay of "oct": info.month = mOct
of "jun": of "nov": info.month = mNov
info.month = mJun of "dec": info.month = mDec
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: else:
raise newException(ValueError, raise newException(ValueError,
"Couldn't parse month (MMM), got: " & value) "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]) "Couldn't parse timezone offset (zzz), got: " & value[j])
j += 6 j += 6
of "ZZZ": of "ZZZ":
info.tzname = value[j..j+2].toUpper() info.tzname = value[j..j+2].toUpperAscii()
j += 3 j += 3
else: else:
# Ignore the token and move forward in the value string by the same length # 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 = proc shouldRun(testName: string): bool =
result = true 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`` ## Declare a test suite identified by `name` with optional ``setup``
## and/or ``teardown`` section. ## 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
## [OK] (2 + -2) != 4 ## [OK] (2 + -2) != 4
block: block:
template setup(setupBody: stmt): stmt {.immediate, dirty.} = template setup(setupBody: untyped) {.dirty.} =
var testSetupIMPLFlag = true 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 var testTeardownIMPLFlag = true
template testTeardownIMPL: stmt {.immediate, dirty.} = teardownBody template testTeardownIMPL: untyped {.dirty.} = teardownBody
body body
@ -135,7 +135,7 @@ proc testDone(name: string, s: TestStatus) =
else: else:
rawPrint() rawPrint()
template test*(name: expr, body: stmt): stmt {.immediate, dirty.} = template test*(name, body) {.dirty.} =
## Define a single test case identified by `name`. ## Define a single test case identified by `name`.
## ##
## .. code-block:: nim ## .. code-block:: nim
@ -226,7 +226,7 @@ template skip* =
testStatusIMPL = SKIPPED testStatusIMPL = SKIPPED
checkpoints = @[] checkpoints = @[]
macro check*(conditions: stmt): stmt {.immediate.} = macro check*(conditions: untyped): untyped =
## Verify if a statement or a list of statements is true. ## Verify if a statement or a list of statements is true.
## A helpful error message and set checkpoints are printed out on ## A helpful error message and set checkpoints are printed out on
## failure (if ``outputLevel`` is not ``PRINT_NONE``). ## 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)) 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 ## Same as `check` except any failed test causes the program to quit
## immediately. Any teardown statements are not executed and the failed ## immediately. Any teardown statements are not executed and the failed
## test output is not generated. ## test output is not generated.
@ -328,7 +328,7 @@ template require*(conditions: stmt): stmt {.immediate.} =
check conditions check conditions
abortOnError = savedAbortOnError 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`. ## Test if `body` raises an exception found in the passed `exceptions`.
## The test passes if the raised exception is part of the acceptable ## The test passes if the raised exception is part of the acceptable
## exceptions. Otherwise, it fails. ## 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 `<` *[T](x, y: ptr T): bool {.magic: "LtPtr", noSideEffect.}
proc `<` *(x, y: pointer): 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)``. ## unequals operator. This is a shorthand for ``not (x == y)``.
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``. ## "is greater or equals" operator. This is the same as ``y <= x``.
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``. ## "is greater" operator. This is the same as ``y < x``.
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) ## assert((1..3).contains(4) == false)
result = s.a <= value and value <= s.b 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 ## Sugar for contains
## ##
## .. code-block:: Nim ## .. code-block:: Nim
## assert(1 in (1..3) == true) ## assert(1 in (1..3) == true)
## assert(5 in (1..3) == false) ## 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 ## Sugar for not containing
## ##
## .. code-block:: Nim ## .. 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[int](3) == 3)
## assert(test[string]("xyz") == 0) ## 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)``. ## Negated version of `is`. Equivalent to ``not(x is y)``.
proc `of` *[T, S](x: T, y: S): bool {.magic: "Of", noSideEffect.} 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 ## swaps the values `a` and `b`. This is often more efficient than
## ``tmp = a; a = b; b = tmp``. Particularly useful for sorting algorithms. ## ``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. ## treats `x` and `y` as unsigned and compares them.
## Returns true iff ``unsigned(x) >= unsigned(y)``. ## 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. ## treats `x` and `y` as unsigned and compares them.
## Returns true iff ``unsigned(x) > unsigned(y)``. ## Returns true iff ``unsigned(x) > unsigned(y)``.
@ -1874,7 +1874,7 @@ iterator countdown*[T](a, b: T, step = 1): T {.inline.} =
yield res yield res
dec(res, step) dec(res, step)
template countupImpl(incr: stmt) {.immediate, dirty.} = template countupImpl(incr: untyped) {.dirty.} =
when T is IntLikeForCount: when T is IntLikeForCount:
var res = int(a) var res = int(a)
while res <= int(b): while res <= int(b):
@ -3181,7 +3181,7 @@ proc `/`*(x, y: int): float {.inline, noSideEffect.} =
## integer division that results in a float. ## integer division that results in a float.
result = toFloat(x) / toFloat(y) 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: # make room for additional elements or cut:
var slen = s.len var slen = s.len
var shift = b.len - L var shift = b.len - L
@ -3467,7 +3467,7 @@ iterator mitems*(a: var string): var char {.inline.} =
when not defined(nimhygiene): when not defined(nimhygiene):
{.pragma: inject.} {.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 ## Sets an assertion failure handler that will intercept any assert
## statements following `onFailedAssert` in the current module scope. ## 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) ## e.lineinfo = instantiationInfo(-2)
## raise e ## raise e
## ##
template failedAssertImpl(msgIMPL: string): stmt {.dirty.} = template failedAssertImpl(msgIMPL: string): untyped {.dirty.} =
let msg = msgIMPL let msg = msgIMPL
code code
@ -3643,7 +3643,7 @@ proc `==` *(x, y: cstring): bool {.magic: "EqCString", noSideEffect,
elif x.isNil or y.isNil: result = false elif x.isNil or y.isNil: result = false
else: result = strcmp(x, y) == 0 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 ## Useful when creating a closure in a loop to capture local loop variables by
## their current iteration values. Example: ## their current iteration values. Example:
## ##

View file

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

View file

@ -1,7 +1,9 @@
version 1.0 battle plan version 1.0 battle plan
======================= =======================
- Deprecate ``immediate`` for templates and macros - tests/stdlib/tnre.nim
- tests/closure/tflatmap.nim
- fix "high priority" bugs - fix "high priority" bugs
- try to fix as many compiler crashes as reasonable - try to fix as many compiler crashes as reasonable

View file

@ -30,6 +30,10 @@ Changes affecting backwards compatibility
discussion. discussion.
- Overloading the special operators ``.``, ``.()``, ``.=``, ``()`` now - Overloading the special operators ``.``, ``.()``, ``.=``, ``()`` now
should be enabled via ``{.experimental.}``. 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 Library Additions