Remove expr/stmt (#5857)

This commit is contained in:
Arne Döring 2017-07-25 09:28:23 +02:00 • committed by Andreas Rumpf
commit 000b8afd26
168 changed files with 497 additions and 529 deletions

View file

@ -104,9 +104,9 @@ proc mapCallConv(cc: TCallingConvention, info: TLineInfo): TABI =
else: else:
globalError(info, "cannot map calling convention to FFI") globalError(info, "cannot map calling convention to FFI")
template rd(T, p: expr): expr {.immediate.} = (cast[ptr T](p))[] template rd(T, p: untyped): untyped = (cast[ptr T](p))[]
template wr(T, p, v: expr) {.immediate.} = (cast[ptr T](p))[] = v template wr(T, p, v: untyped): untyped = (cast[ptr T](p))[] = v
template `+!`(x, y: expr): expr {.immediate.} = template `+!`(x, y: untyped): untyped =
cast[pointer](cast[ByteAddress](x) + y) cast[pointer](cast[ByteAddress](x) + y)
proc packSize(v: PNode, typ: PType): int = proc packSize(v: PNode, typ: PType): int =
@ -171,7 +171,7 @@ const maxPackDepth = 20
var packRecCheck = 0 var packRecCheck = 0
proc pack(v: PNode, typ: PType, res: pointer) = proc pack(v: PNode, typ: PType, res: pointer) =
template awr(T, v: expr) {.immediate, dirty.} = template awr(T, v: untyped): untyped =
wr(T, res, v) wr(T, res, v)
case typ.kind case typ.kind
@ -302,7 +302,7 @@ proc canonNodeKind(k: TNodeKind): TNodeKind =
else: result = k else: result = k
proc unpack(x: pointer, typ: PType, n: PNode): PNode = proc unpack(x: pointer, typ: PType, n: PNode): PNode =
template aw(k, v, field: expr) {.immediate, dirty.} = template aw(k, v, field: untyped): untyped =
if n.isNil: if n.isNil:
result = newNode(k) result = newNode(k)
result.typ = typ result.typ = typ
@ -326,9 +326,9 @@ proc unpack(x: pointer, typ: PType, n: PNode): PNode =
result.kind = nkNilLit result.kind = nkNilLit
result.typ = typ result.typ = typ
template awi(kind, v: expr) {.immediate, dirty.} = aw(kind, v, intVal) template awi(kind, v: untyped): untyped = aw(kind, v, intVal)
template awf(kind, v: expr) {.immediate, dirty.} = aw(kind, v, floatVal) template awf(kind, v: untyped): untyped = aw(kind, v, floatVal)
template aws(kind, v: expr) {.immediate, dirty.} = aw(kind, v, strVal) template aws(kind, v: untyped): untyped = aw(kind, v, strVal)
case typ.kind case typ.kind
of tyBool: awi(nkIntLit, rd(bool, x).ord) of tyBool: awi(nkIntLit, rd(bool, x).ord)

View file

@ -12,14 +12,14 @@
discard """ discard """
hygienic templates: hygienic templates:
template `||` (a, b: expr): expr = template `||` (a, b: untyped): untyped =
let aa = a let aa = a
if aa: aa else: b if aa: aa else: b
var var
a, b: T a, b: T
a || b || a echo a || b || a
Each evaluation context has to be different and we need to perform Each evaluation context has to be different and we need to perform
some form of preliminary symbol lookup in template definitions. Hygiene is some form of preliminary symbol lookup in template definitions. Hygiene is

View file

@ -1,5 +0,0 @@
template tests*(body: stmt) {.immediate.} =
when defined(selftest):
when not declared(unittest): import unittest
body

View file

@ -1,6 +1,6 @@
# All and any # All and any
template all(container, cond: expr): expr {.immediate.} = template all(container, cond: untyped): bool =
block: block:
var result = true var result = true
for it in items(container): for it in items(container):
@ -9,7 +9,7 @@ template all(container, cond: expr): expr {.immediate.} =
break break
result result
template any(container, cond: expr): expr {.immediate.} = template any(container, cond: untyped): bool =
block: block:
var result = false var result = false
for it in items(container): for it in items(container):

View file

@ -97,7 +97,7 @@ proc newObj(typ: PNimType, size: int): pointer {.importCompilerProc.}
proc newSeq(typ: PNimType, len: int): pointer {.importCompilerProc.} proc newSeq(typ: PNimType, len: int): pointer {.importCompilerProc.}
proc objectInit(dest: pointer, typ: PNimType) {.importCompilerProc.} proc objectInit(dest: pointer, typ: PNimType) {.importCompilerProc.}
template `+!!`(a, b: expr): expr = cast[pointer](cast[ByteAddress](a) + b) template `+!!`(a, b): untyped = cast[pointer](cast[ByteAddress](a) + b)
proc getDiscriminant(aa: pointer, n: ptr TNimNode): int = proc getDiscriminant(aa: pointer, n: ptr TNimNode): int =
assert(n.kind == nkCase) assert(n.kind == nkCase)

View file

@ -206,16 +206,16 @@ proc htons*(x: int16): int16 =
## order, this is a no-op; otherwise, it performs a 2-byte swap operation. ## order, this is a no-op; otherwise, it performs a 2-byte swap operation.
result = sockets.ntohs(x) result = sockets.ntohs(x)
template ntohl(x: uint32): expr = template ntohl(x: uint32): uint32 =
cast[uint32](sockets.ntohl(cast[int32](x))) cast[uint32](sockets.ntohl(cast[int32](x)))
template ntohs(x: uint16): expr = template ntohs(x: uint16): uint16 =
cast[uint16](sockets.ntohs(cast[int16](x))) cast[uint16](sockets.ntohs(cast[int16](x)))
template htonl(x: uint32): expr = template htonl(x: uint32): uint32 =
sockets.ntohl(x) sockets.ntohl(x)
template htons(x: uint16): expr = template htons(x: uint16): uint16 =
sockets.ntohs(x) sockets.ntohs(x)
when defined(Posix): when defined(Posix):
@ -442,14 +442,13 @@ proc parseIp4*(s: string): BiggestInt =
if s[i] != '\0': invalidIp4(s) if s[i] != '\0': invalidIp4(s)
result = BiggestInt(a shl 24 or b shl 16 or c shl 8 or d) result = BiggestInt(a shl 24 or b shl 16 or c shl 8 or d)
template gaiNim(a, p, h, list: expr): stmt = template gaiNim(a, p, h, list: untyped): untyped =
block: var gaiResult = getaddrinfo(a, $p, addr(h), list)
var gaiResult = getaddrinfo(a, $p, addr(h), list) if gaiResult != 0'i32:
if gaiResult != 0'i32: when defined(windows):
when defined(windows): raiseOSError(osLastError())
raiseOSError(osLastError()) else:
else: raiseOSError(osLastError(), $gai_strerror(gaiResult))
raiseOSError(osLastError(), $gai_strerror(gaiResult))
proc bindAddr*(socket: Socket, port = Port(0), address = "") {. proc bindAddr*(socket: Socket, port = Port(0), address = "") {.
tags: [ReadIOEffect].} = tags: [ReadIOEffect].} =
@ -493,8 +492,8 @@ proc getSockName*(socket: Socket): Port =
raiseOSError(osLastError()) raiseOSError(osLastError())
result = Port(sockets.ntohs(name.sin_port)) result = Port(sockets.ntohs(name.sin_port))
template acceptAddrPlain(noClientRet, successRet: expr, template acceptAddrPlain(noClientRet, successRet: int,
sslImplementation: stmt): stmt {.immediate.} = sslImplementation: untyped): untyped =
assert(client != nil) assert(client != nil)
var sockAddress: Sockaddr_in var sockAddress: Sockaddr_in
var addrLen = sizeof(sockAddress).SockLen var addrLen = sizeof(sockAddress).SockLen
@ -594,7 +593,7 @@ when defined(ssl):
## ##
## ``AcceptNoClient`` will be returned when no client is currently attempting ## ``AcceptNoClient`` will be returned when no client is currently attempting
## to connect. ## to connect.
template doHandshake(): stmt = template doHandshake(): untyped =
when defined(ssl): when defined(ssl):
if server.isSSL: if server.isSSL:
client.setBlocking(false) client.setBlocking(false)
@ -1278,7 +1277,7 @@ proc recvLine*(socket: Socket, line: var TaintedString, timeout = -1): bool {.
## **Deprecated since version 0.9.2**: This function has been deprecated in ## **Deprecated since version 0.9.2**: This function has been deprecated in
## favour of readLine. ## favour of readLine.
template addNLIfEmpty(): stmt = template addNLIfEmpty(): untyped =
if line.len == 0: if line.len == 0:
line.add("\c\L") line.add("\c\L")
@ -1319,7 +1318,7 @@ proc readLine*(socket: Socket, line: var TaintedString, timeout = -1) {.
## A timeout can be specified in milliseconds, if data is not received within ## A timeout can be specified in milliseconds, if data is not received within
## the specified time an ETimeout exception will be raised. ## the specified time an ETimeout exception will be raised.
template addNLIfEmpty(): stmt = template addNLIfEmpty(): untyped =
if line.len == 0: if line.len == 0:
line.add("\c\L") line.add("\c\L")

View file

@ -16,7 +16,7 @@ proc checkNil(arg: string): string =
else: else:
return arg return arg
template formatStr*(howExpr, namegetter, idgetter: expr): expr = template formatStr*(howExpr, namegetter, idgetter): untyped =
let how = howExpr let how = howExpr
var val = newStringOfCap(how.len) var val = newStringOfCap(how.len)
var i = 0 var i = 0

View file

@ -765,7 +765,7 @@ proc renderTocEntries*(d: var RstGenerator, j: var int, lvl: int,
result.add(tmp) result.add(tmp)
proc renderImage(d: PDoc, n: PRstNode, result: var string) = proc renderImage(d: PDoc, n: PRstNode, result: var string) =
template valid(s): expr = template valid(s): bool =
s.len > 0 and allCharsInSet(s, {'.','/',':','%','_','\\','\128'..'\xFF'} + s.len > 0 and allCharsInSet(s, {'.','/',':','%','_','\\','\128'..'\xFF'} +
Digits + Letters + WhiteSpace) Digits + Letters + WhiteSpace)
let let
@ -1194,7 +1194,7 @@ proc defaultConfig*(): StringTableRef =
## ``rstToHtml`` to generate the bare minimum HTML. ## ``rstToHtml`` to generate the bare minimum HTML.
result = newStringTable(modeStyleInsensitive) result = newStringTable(modeStyleInsensitive)
template setConfigVar(key, val: expr) = template setConfigVar(key, val) =
result[key] = val result[key] = val
# If you need to modify these values, it might be worth updating the template # If you need to modify these values, it might be worth updating the template

View file

@ -174,7 +174,7 @@ var
# Compare a character C to a value VAL from the `cc' array in a # Compare a character C to a value VAL from the `cc' array in a
# `struct termios'. If VAL is _POSIX_VDISABLE, no character can match it. # `struct termios'. If VAL is _POSIX_VDISABLE, no character can match it.
template cceq*(val, c: expr): expr = template cceq*(val, c): untyped =
c == val and val != POSIX_VDISABLE c == val and val != POSIX_VDISABLE
# Return the output baud rate stored in *TERMIOS_P. # Return the output baud rate stored in *TERMIOS_P.

View file

@ -1317,7 +1317,7 @@ proc recvLine*(socket: AsyncFD): Future[string] {.async, deprecated.} =
## ##
## **Deprecated since version 0.15.0**: Use ``asyncnet.recvLine()`` instead. ## **Deprecated since version 0.15.0**: Use ``asyncnet.recvLine()`` instead.
template addNLIfEmpty(): stmt = template addNLIfEmpty(): untyped =
if result.len == 0: if result.len == 0:
result.add("\c\L") result.add("\c\L")

View file

@ -220,7 +220,7 @@ when defineSsl:
raiseSSLError("Cannot appease SSL.") raiseSSLError("Cannot appease SSL.")
template sslLoop(socket: AsyncSocket, flags: set[SocketFlag], template sslLoop(socket: AsyncSocket, flags: set[SocketFlag],
op: expr) = op: untyped) =
var opResult {.inject.} = -1.cint var opResult {.inject.} = -1.cint
while opResult < 0: while opResult < 0:
# Call the desired operation. # Call the desired operation.
@ -490,7 +490,7 @@ proc recvLineInto*(socket: AsyncSocket, resString: FutureVar[string],
# them when the result future is completed. # them when the result future is completed.
# Can we replace the result future with the FutureVar? # Can we replace the result future with the FutureVar?
template addNLIfEmpty(): stmt = template addNLIfEmpty(): untyped =
if resString.mget.len == 0: if resString.mget.len == 0:
resString.mget.add("\c\L") resString.mget.add("\c\L")

View file

@ -116,13 +116,13 @@ proc safeArccos(v:float):float=
return arccos(clamp(v,-1.0,1.0)) return arccos(clamp(v,-1.0,1.0))
template makeBinOpVector(s:expr)= template makeBinOpVector(s) =
## implements binary operators ``+``, ``-``, ``*`` and ``/`` for vectors ## implements binary operators ``+``, ``-``, ``*`` and ``/`` for vectors
proc s*(a,b:Vector2d):Vector2d {.inline,noInit.} = vector2d(s(a.x,b.x),s(a.y,b.y)) proc s*(a,b:Vector2d):Vector2d {.inline,noInit.} = vector2d(s(a.x,b.x),s(a.y,b.y))
proc s*(a:Vector2d,b:float):Vector2d {.inline,noInit.} = vector2d(s(a.x,b),s(a.y,b)) proc s*(a:Vector2d,b:float):Vector2d {.inline,noInit.} = vector2d(s(a.x,b),s(a.y,b))
proc s*(a:float,b:Vector2d):Vector2d {.inline,noInit.} = vector2d(s(a,b.x),s(a,b.y)) proc s*(a:float,b:Vector2d):Vector2d {.inline,noInit.} = vector2d(s(a,b.x),s(a,b.y))
template makeBinOpAssignVector(s:expr)= template makeBinOpAssignVector(s)=
## implements inplace binary operators ``+=``, ``-=``, ``/=`` and ``*=`` for vectors ## implements inplace binary operators ``+=``, ``-=``, ``/=`` and ``*=`` for vectors
proc s*(a:var Vector2d,b:Vector2d) {.inline.} = s(a.x,b.x) ; s(a.y,b.y) proc s*(a:var Vector2d,b:Vector2d) {.inline.} = s(a.x,b.x) ; s(a.y,b.y)
proc s*(a:var Vector2d,b:float) {.inline.} = s(a.x,b) ; s(a.y,b) proc s*(a:var Vector2d,b:float) {.inline.} = s(a.x,b) ; s(a.y,b)
@ -853,5 +853,3 @@ proc degToRad*(deg:float):float {.inline.}=
proc radToDeg*(rad:float):float {.inline.}= proc radToDeg*(rad:float):float {.inline.}=
## converts `rad` radians to degrees ## converts `rad` radians to degrees
rad * RAD2DEGCONST rad * RAD2DEGCONST

View file

@ -116,7 +116,7 @@ proc safeArccos(v:float):float=
## due to rounding issues ## due to rounding issues
return arccos(clamp(v,-1.0,1.0)) return arccos(clamp(v,-1.0,1.0))
template makeBinOpVector(s:expr)= template makeBinOpVector(s) =
proc s*(a,b:Vector3d):Vector3d {.inline,noInit.} = proc s*(a,b:Vector3d):Vector3d {.inline,noInit.} =
vector3d(s(a.x,b.x),s(a.y,b.y),s(a.z,b.z)) vector3d(s(a.x,b.x),s(a.y,b.y),s(a.z,b.z))
proc s*(a:Vector3d,b:float):Vector3d {.inline,noInit.} = proc s*(a:Vector3d,b:float):Vector3d {.inline,noInit.} =
@ -124,7 +124,7 @@ template makeBinOpVector(s:expr)=
proc s*(a:float,b:Vector3d):Vector3d {.inline,noInit.} = proc s*(a:float,b:Vector3d):Vector3d {.inline,noInit.} =
vector3d(s(a,b.x),s(a,b.y),s(a,b.z)) vector3d(s(a,b.x),s(a,b.y),s(a,b.z))
template makeBinOpAssignVector(s:expr)= template makeBinOpAssignVector(s) =
proc s*(a:var Vector3d,b:Vector3d) {.inline.} = proc s*(a:var Vector3d,b:Vector3d) {.inline.} =
s(a.x,b.x); s(a.y,b.y); s(a.z,b.z) s(a.x,b.x); s(a.y,b.y); s(a.z,b.z)
proc s*(a:var Vector3d,b:float) {.inline.} = proc s*(a:var Vector3d,b:float) {.inline.} =

View file

@ -143,15 +143,16 @@ proc `[]=`*[T](c: var CritBitTree[T], key: string, val: T) =
var n = rawInsert(c, key) var n = rawInsert(c, key)
n.val = val n.val = val
template get[T](c: CritBitTree[T], key: string): T {.immediate.} = template get[T](c: CritBitTree[T], key: string): T =
let n = rawGet(c, key) let n = rawGet(c, key)
if n != nil: result = n.val if n == nil:
else:
when compiles($key): when compiles($key):
raise newException(KeyError, "key not found: " & $key) raise newException(KeyError, "key not found: " & $key)
else: else:
raise newException(KeyError, "key not found") raise newException(KeyError, "key not found")
n.val
proc `[]`*[T](c: CritBitTree[T], key: string): T {.inline, deprecatedGet.} = proc `[]`*[T](c: CritBitTree[T], key: string): T {.inline, deprecatedGet.} =
## retrieves the value at ``c[key]``. If `key` is not in `t`, the ## retrieves the value at ``c[key]``. If `key` is not in `t`, the
## ``KeyError`` exception is raised. One can check with ``hasKey`` whether ## ``KeyError`` exception is raised. One can check with ``hasKey`` whether

View file

@ -189,7 +189,7 @@ iterator items*(s: IntSet): int {.inline.} =
inc(i) inc(i)
r = r.next r = r.next
template dollarImpl(): stmt = template dollarImpl(): untyped =
result = "{" result = "{"
for key in items(s): for key in items(s):
if result.len > 1: result.add(", ") if result.len > 1: result.add(", ")

View file

@ -455,7 +455,7 @@ template anyIt*(seq1, pred: untyped): bool =
break break
result result
template toSeq*(iter: untyped): untyped {.oldimmediate.} = template toSeq*(iter: untyped): untyped =
## Transforms any iterator into a sequence. ## Transforms any iterator into a sequence.
## ##
## Example: ## Example:

View file

@ -25,7 +25,7 @@ type
counter, dataLen: int counter, dataLen: int
lock: Lock lock: Lock
template maxHash(t): expr = t.dataLen-1 template maxHash(t): untyped = t.dataLen-1
include tableimpl include tableimpl

View file

@ -85,7 +85,7 @@ template addImpl(enlarge) {.dirty.} =
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) {.oldimmediate, dirty.} = 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)
@ -93,7 +93,7 @@ template maybeRehashPutImpl(enlarge) {.oldimmediate, dirty.} =
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) {.oldimmediate, dirty.} = 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

View file

@ -19,18 +19,18 @@ type
proc `==` *(a, b: Color): bool {.borrow.} proc `==` *(a, b: Color): bool {.borrow.}
## compares two colors. ## compares two colors.
template extract(a: Color, r, g, b: expr) {.immediate.}= template extract(a: Color, r, g, b: untyped) =
var r = a.int shr 16 and 0xff var r = a.int shr 16 and 0xff
var g = a.int shr 8 and 0xff var g = a.int shr 8 and 0xff
var b = a.int and 0xff var b = a.int and 0xff
template rawRGB(r, g, b: int): expr = template rawRGB(r, g, b: int): Color =
Color(r shl 16 or g shl 8 or b) Color(r shl 16 or g shl 8 or b)
template colorOp(op: expr) {.immediate.} = template colorOp(op): Color =
extract(a, ar, ag, ab) extract(a, ar, ag, ab)
extract(b, br, bg, bb) extract(b, br, bg, bb)
result = rawRGB(op(ar, br), op(ag, bg), op(ab, bb)) rawRGB(op(ar, br), op(ag, bg), op(ab, bb))
proc satPlus(a, b: int): int {.inline.} = proc satPlus(a, b: int): int {.inline.} =
result = a +% b result = a +% b
@ -67,12 +67,12 @@ proc intensity*(a: Color, f: float): Color =
if b >% 255: b = 255 if b >% 255: b = 255
result = rawRGB(r, g, b) result = rawRGB(r, g, b)
template mix*(a, b: Color, fn: expr): expr = template mix*(a, b: Color, fn: untyped): untyped =
## uses `fn` to mix the colors `a` and `b`. `fn` is invoked for each component ## uses `fn` to mix the colors `a` and `b`. `fn` is invoked for each component
## R, G, and B. This is a template because `fn` should be inlined and the ## R, G, and B. This is a template because `fn` should be inlined and the
## compiler cannot inline proc pointers yet. If `fn`'s result is not in the ## compiler cannot inline proc pointers yet. If `fn`'s result is not in the
## range[0..255], it will be saturated to be so. ## range[0..255], it will be saturated to be so.
template `><` (x: expr): expr = template `><` (x: untyped): untyped =
# keep it in the range 0..255 # keep it in the range 0..255
block: block:
var y = x # eval only once var y = x # eval only once

View file

@ -409,20 +409,20 @@ proc preferSpawn*(): bool =
## it is not necessary to call this directly; use 'spawnX' instead. ## it is not necessary to call this directly; use 'spawnX' instead.
result = gSomeReady.counter > 0 result = gSomeReady.counter > 0
proc spawn*(call: expr): expr {.magic: "Spawn".} proc spawn*(call: typed): void {.magic: "Spawn".}
## always spawns a new task, so that the 'call' is never executed on ## always spawns a new task, so that the 'call' is never executed on
## the calling thread. 'call' has to be proc call 'p(...)' where 'p' ## the calling thread. 'call' has to be proc call 'p(...)' where 'p'
## is gcsafe and has a return type that is either 'void' or compatible ## is gcsafe and has a return type that is either 'void' or compatible
## with ``FlowVar[T]``. ## with ``FlowVar[T]``.
proc pinnedSpawn*(id: ThreadId; call: expr): expr {.magic: "Spawn".} proc pinnedSpawn*(id: ThreadId; call: typed): void {.magic: "Spawn".}
## always spawns a new task on the worker thread with ``id``, so that ## always spawns a new task on the worker thread with ``id``, so that
## the 'call' is **always** executed on ## the 'call' is **always** executed on
## the thread. 'call' has to be proc call 'p(...)' where 'p' ## the thread. 'call' has to be proc call 'p(...)' where 'p'
## is gcsafe and has a return type that is either 'void' or compatible ## is gcsafe and has a return type that is either 'void' or compatible
## with ``FlowVar[T]``. ## with ``FlowVar[T]``.
template spawnX*(call: expr): expr = template spawnX*(call): void =
## spawns a new task if a CPU core is ready, otherwise executes the ## spawns a new task if a CPU core is ready, otherwise executes the
## call in the calling thread. Usually it is advised to ## call in the calling thread. Usually it is advised to
## use 'spawn' in order to not block the producer for an unknown ## use 'spawn' in order to not block the producer for an unknown
@ -431,7 +431,7 @@ template spawnX*(call: expr): expr =
## with ``FlowVar[T]``. ## with ``FlowVar[T]``.
(if preferSpawn(): spawn call else: call) (if preferSpawn(): spawn call else: call)
proc parallel*(body: stmt) {.magic: "Parallel".} proc parallel*(body: untyped) {.magic: "Parallel".}
## a parallel section can be used to execute a block in parallel. ``body`` ## a parallel section can be used to execute a block in parallel. ``body``
## has to be in a DSL that is a particular subset of the language. Please ## has to be in a DSL that is a particular subset of the language. Please
## refer to the manual for further information. ## refer to the manual for further information.

View file

@ -123,7 +123,7 @@ proc open*(filename: string, mode: FileMode = fmRead,
result.size = 0 result.size = 0
when defined(windows): when defined(windows):
template fail(errCode: OSErrorCode, msg: expr) = template fail(errCode: OSErrorCode, msg: untyped) =
rollback() rollback()
if result.fHandle != 0: discard closeHandle(result.fHandle) if result.fHandle != 0: discard closeHandle(result.fHandle)
if result.mapHandle != 0: discard closeHandle(result.mapHandle) if result.mapHandle != 0: discard closeHandle(result.mapHandle)
@ -131,7 +131,7 @@ proc open*(filename: string, mode: FileMode = fmRead,
# return false # return false
#raise newException(EIO, msg) #raise newException(EIO, msg)
template callCreateFile(winApiProc, filename: expr): expr = template callCreateFile(winApiProc, filename): untyped =
winApiProc( winApiProc(
filename, filename,
# GENERIC_ALL != (GENERIC_READ or GENERIC_WRITE) # GENERIC_ALL != (GENERIC_READ or GENERIC_WRITE)
@ -198,7 +198,7 @@ proc open*(filename: string, mode: FileMode = fmRead,
result.fHandle = INVALID_HANDLE_VALUE result.fHandle = INVALID_HANDLE_VALUE
else: else:
template fail(errCode: OSErrorCode, msg: expr) = template fail(errCode: OSErrorCode, msg: string) =
rollback() rollback()
if result.handle != -1: discard close(result.handle) if result.handle != -1: discard close(result.handle)
raiseOSError(errCode) raiseOSError(errCode)

View file

@ -797,7 +797,7 @@ when false: #defineSsl:
## ##
## ``AcceptNoClient`` will be returned when no client is currently attempting ## ``AcceptNoClient`` will be returned when no client is currently attempting
## to connect. ## to connect.
template doHandshake(): stmt = template doHandshake(): untyped =
when defineSsl: when defineSsl:
if server.isSSL: if server.isSSL:
client.setBlocking(false) client.setBlocking(false)

View file

@ -139,7 +139,7 @@ proc addChoice(dest: var Peg, elem: Peg) =
else: add(dest, elem) else: add(dest, elem)
else: add(dest, elem) else: add(dest, elem)
template multipleOp(k: PegKind, localOpt: expr) = template multipleOp(k: PegKind, localOpt: untyped) =
result.kind = k result.kind = k
result.sons = @[] result.sons = @[]
for x in items(a): for x in items(a):
@ -328,32 +328,32 @@ proc newNonTerminal*(name: string, line, column: int): NonTerminal {.
result.line = line result.line = line
result.col = column result.col = column
template letters*: expr = template letters*: Peg =
## expands to ``charset({'A'..'Z', 'a'..'z'})`` ## expands to ``charset({'A'..'Z', 'a'..'z'})``
charSet({'A'..'Z', 'a'..'z'}) charSet({'A'..'Z', 'a'..'z'})
template digits*: expr = template digits*: Peg =
## expands to ``charset({'0'..'9'})`` ## expands to ``charset({'0'..'9'})``
charSet({'0'..'9'}) charSet({'0'..'9'})
template whitespace*: expr = template whitespace*: Peg =
## expands to ``charset({' ', '\9'..'\13'})`` ## expands to ``charset({' ', '\9'..'\13'})``
charSet({' ', '\9'..'\13'}) charSet({' ', '\9'..'\13'})
template identChars*: expr = template identChars*: Peg =
## expands to ``charset({'a'..'z', 'A'..'Z', '0'..'9', '_'})`` ## expands to ``charset({'a'..'z', 'A'..'Z', '0'..'9', '_'})``
charSet({'a'..'z', 'A'..'Z', '0'..'9', '_'}) charSet({'a'..'z', 'A'..'Z', '0'..'9', '_'})
template identStartChars*: expr = template identStartChars*: Peg =
## expands to ``charset({'A'..'Z', 'a'..'z', '_'})`` ## expands to ``charset({'A'..'Z', 'a'..'z', '_'})``
charSet({'a'..'z', 'A'..'Z', '_'}) charSet({'a'..'z', 'A'..'Z', '_'})
template ident*: expr = template ident*: Peg =
## same as ``[a-zA-Z_][a-zA-z_0-9]*``; standard identifier ## same as ``[a-zA-Z_][a-zA-z_0-9]*``; standard identifier
sequence(charSet({'a'..'z', 'A'..'Z', '_'}), sequence(charSet({'a'..'z', 'A'..'Z', '_'}),
*charSet({'a'..'z', 'A'..'Z', '0'..'9', '_'})) *charSet({'a'..'z', 'A'..'Z', '0'..'9', '_'}))
template natural*: expr = template natural*: Peg =
## same as ``\d+`` ## same as ``\d+``
+digits +digits
@ -514,10 +514,10 @@ proc bounds*(c: Captures,
when not useUnicode: when not useUnicode:
type type
Rune = char Rune = char
template fastRuneAt(s, i, ch: expr) = template fastRuneAt(s, i, ch) =
ch = s[i] ch = s[i]
inc(i) inc(i)
template runeLenAt(s, i: expr): expr = 1 template runeLenAt(s, i): untyped = 1
proc isAlpha(a: char): bool {.inline.} = return a in {'a'..'z','A'..'Z'} proc isAlpha(a: char): bool {.inline.} = return a in {'a'..'z','A'..'Z'}
proc isUpper(a: char): bool {.inline.} = return a in {'A'..'Z'} proc isUpper(a: char): bool {.inline.} = return a in {'A'..'Z'}
@ -735,7 +735,7 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {.
else: result = -1 else: result = -1
of pkRule, pkList: assert false of pkRule, pkList: assert false
template fillMatches(s, caps, c: expr) = template fillMatches(s, caps, c) =
for k in 0..c.ml-1: for k in 0..c.ml-1:
let startIdx = c.matches[k][0] let startIdx = c.matches[k][0]
let endIdx = c.matches[k][1] let endIdx = c.matches[k][1]

View file

@ -46,12 +46,12 @@ type
num, i, lineLen: int num, i, lineLen: int
{.deprecated: [TFormatParser: FormatParser].} {.deprecated: [TFormatParser: FormatParser].}
template call(x: stmt) {.immediate.} = template call(x: untyped): untyped =
p.i = i p.i = i
x x
i = p.i i = p.i
template callNoLineLenTracking(x: stmt) {.immediate.} = template callNoLineLenTracking(x: untyped): untyped =
let oldLineLen = p.lineLen let oldLineLen = p.lineLen
p.i = i p.i = i
x x

View file

@ -578,7 +578,7 @@ template styledEchoProcessArg(f: File, cmd: TerminalCmd) =
when cmd == resetStyle: when cmd == resetStyle:
resetAttributes(f) resetAttributes(f)
macro styledWriteLine*(f: File, m: varargs[expr]): stmt = macro styledWriteLine*(f: File, m: varargs[typed]): untyped =
## Similar to ``writeLine``, but treating terminal style arguments specially. ## Similar to ``writeLine``, but treating terminal style arguments specially.
## When some argument is ``Style``, ``set[Style]``, ``ForegroundColor``, ## When some argument is ``Style``, ``set[Style]``, ``ForegroundColor``,
## ``BackgroundColor`` or ``TerminalCmd`` then it is not sent directly to ## ``BackgroundColor`` or ``TerminalCmd`` then it is not sent directly to
@ -614,16 +614,13 @@ macro styledWriteLine*(f: File, m: varargs[expr]): stmt =
result.add(newCall(bindSym"write", f, newStrLitNode("\n"))) result.add(newCall(bindSym"write", f, newStrLitNode("\n")))
if reset: result.add(newCall(bindSym"resetAttributes", f)) if reset: result.add(newCall(bindSym"resetAttributes", f))
macro callStyledEcho(args: varargs[expr]): stmt = macro styledEcho*(args: varargs[untyped]): untyped =
## Echoes styles arguments to stdout using ``styledWriteLine``.
result = newCall(bindSym"styledWriteLine") result = newCall(bindSym"styledWriteLine")
result.add(bindSym"stdout") result.add(bindSym"stdout")
for arg in children(args[0][1]): for arg in children(args):
result.add(arg) result.add(arg)
template styledEcho*(args: varargs[expr]): expr =
## Echoes styles arguments to stdout using ``styledWriteLine``.
callStyledEcho(args)
proc getch*(): char = proc getch*(): char =
## Read a single character from the terminal, blocking until it is entered. ## Read a single character from the terminal, blocking until it is entered.
## The character is not printed to the terminal. ## The character is not printed to the terminal.

View file

@ -215,7 +215,7 @@ proc combine*(base: Uri, reference: Uri): Uri =
## let bar = combine(parseUri("http://example.com/foo/bar/"), parseUri("baz")) ## let bar = combine(parseUri("http://example.com/foo/bar/"), parseUri("baz"))
## assert bar.path == "/foo/bar/baz" ## assert bar.path == "/foo/bar/baz"
template setAuthority(dest, src: expr): stmt = template setAuthority(dest, src): untyped =
dest.hostname = src.hostname dest.hostname = src.hostname
dest.username = src.username dest.username = src.username
dest.port = src.port dest.port = src.port

View file

@ -338,7 +338,7 @@ proc xmlConstructor(e: NimNode): NimNode {.compileTime.} =
else: else:
result = newCall("newXmlTree", toStrLit(a)) result = newCall("newXmlTree", toStrLit(a))
macro `<>`*(x: expr): expr {.immediate.} = macro `<>`*(x: untyped): untyped =
## Constructor macro for XML. Example usage: ## Constructor macro for XML. Example usage:
## ##
## .. code-block:: nim ## .. code-block:: nim

View file

@ -80,9 +80,10 @@ type
`nil` {.magic: "Nil".} `nil` {.magic: "Nil".}
expr* {.magic: Expr, deprecated.} ## meta type to denote an expression (for templates) expr* {.magic: Expr, deprecated.} ## meta type to denote an expression (for templates)
## **Deprecated** since version 0.15. Use ``untyped`` instead. ## **Deprecated** since version 0.15. Use ``untyped`` instead.
stmt* {.magic: Stmt, deprecated.} ## meta type to denote a statement (for templates) stmt* {.magic: Stmt, deprecated.} ## meta type to denote a statement (for templates)
## **Deprecated** since version 0.15. Use ``typed`` instead. ## **Deprecated** since version 0.15. Use ``typed`` instead.
void* {.magic: "VoidType".} ## meta type to denote the absence of any type void* {.magic: "VoidType".} ## meta type to denote the absence of any type
auto* {.magic: Expr.} ## meta type for automatic type determination auto* {.magic: Expr.} ## meta type for automatic type determination
any* = distinct auto ## meta type for any supported type any* = distinct auto ## meta type for any supported type
@ -1951,30 +1952,34 @@ iterator countdown*[T](a, b: T, step = 1): T {.inline.} =
yield res yield res
dec(res, step) dec(res, step)
template countupImpl(incr: untyped) {.oldimmediate, dirty.} =
when T is IntLikeForCount:
var res = int(a)
while res <= int(b):
yield T(res)
incr
else:
var res: T = T(a)
while res <= b:
yield res
incr
iterator countup*[S, T](a: S, b: T, step = 1): T {.inline.} = iterator countup*[S, T](a: S, b: T, step = 1): T {.inline.} =
## Counts from ordinal value `a` up to `b` (inclusive) with the given ## Counts from ordinal value `a` up to `b` (inclusive) with the given
## step count. `S`, `T` may be any ordinal type, `step` may only ## step count. `S`, `T` may be any ordinal type, `step` may only
## be positive. **Note**: This fails to count to ``high(int)`` if T = int for ## be positive. **Note**: This fails to count to ``high(int)`` if T = int for
## efficiency reasons. ## efficiency reasons.
countupImpl: when T is IntLikeForCount:
inc(res, step) var res = int(a)
while res <= int(b):
yield T(res)
inc(res, step)
else:
var res: T = T(a)
while res <= b:
yield res
inc(res, step)
iterator `..`*[S, T](a: S, b: T): T {.inline.} = iterator `..`*[S, T](a: S, b: T): T {.inline.} =
## An alias for `countup`. ## An alias for `countup`.
countupImpl: when T is IntLikeForCount:
inc(res) var res = int(a)
while res <= int(b):
yield T(res)
inc(res)
else:
var res: T = T(a)
while res <= b:
yield res
inc(res)
iterator `||`*[S, T](a: S, b: T, annotation=""): T {. iterator `||`*[S, T](a: S, b: T, annotation=""): T {.
inline, magic: "OmpParFor", sideEffect.} = inline, magic: "OmpParFor", sideEffect.} =

View file

@ -203,12 +203,12 @@ proc rawRecv(q: PRawChannel, data: pointer, typ: PNimType) =
storeAux(data, addr(q.data[q.rd * typ.size]), typ, q, mLoad) storeAux(data, addr(q.data[q.rd * typ.size]), typ, q, mLoad)
q.rd = (q.rd + 1) and q.mask q.rd = (q.rd + 1) and q.mask
template lockChannel(q: expr, action: stmt) {.immediate.} = template lockChannel(q, action): untyped =
acquireSys(q.lock) acquireSys(q.lock)
action action
releaseSys(q.lock) releaseSys(q.lock)
template sendImpl(q: expr) {.immediate.} = template sendImpl(q) =
if q.mask == ChannelDeadMask: if q.mask == ChannelDeadMask:
sysFatal(DeadThreadError, "cannot send message; thread died") sysFatal(DeadThreadError, "cannot send message; thread died")
acquireSys(q.lock) acquireSys(q.lock)

View file

@ -276,11 +276,11 @@ proc raiseExceptionAux(e: ref Exception) =
quitOrDebug() quitOrDebug()
else: else:
# ugly, but avoids heap allocations :-) # ugly, but avoids heap allocations :-)
template xadd(buf, s, slen: expr) = template xadd(buf, s, slen) =
if L + slen < high(buf): if L + slen < high(buf):
copyMem(addr(buf[L]), cstring(s), slen) copyMem(addr(buf[L]), cstring(s), slen)
inc L, slen inc L, slen
template add(buf, s: expr) = template add(buf, s) =
xadd(buf, s, s.len) xadd(buf, s, s.len)
var buf: array[0..2000, char] var buf: array[0..2000, char]
var L = 0 var L = 0
@ -387,7 +387,8 @@ when not defined(noSignalHandler):
GC_enable() GC_enable()
else: else:
var msg: cstring var msg: cstring
template asgn(y: expr) = msg = y template asgn(y) =
msg = y
processSignal(sign, asgn) processSignal(sign, asgn)
showErrorMessage(msg) showErrorMessage(msg)
when defined(endb): dbgAborting = true when defined(endb): dbgAborting = true

View file

@ -447,7 +447,7 @@ proc threadProcWrapStackFrame[TArg](thrd: ptr Thread[TArg]) =
else: else:
threadProcWrapDispatch(thrd) threadProcWrapDispatch(thrd)
template threadProcWrapperBody(closure: expr) {.immediate.} = template threadProcWrapperBody(closure: untyped): untyped =
var thrd = cast[ptr Thread[TArg]](closure) var thrd = cast[ptr Thread[TArg]](closure)
var core = thrd.core var core = thrd.core
when declared(globalsSlot): threadVarSetValue(globalsSlot, thrd.core) when declared(globalsSlot): threadVarSetValue(globalsSlot, thrd.core)

View file

@ -8,17 +8,17 @@ proc isPartOf*[S, T](a: S, b: T): TAnalysisResult {.
magic: "IsPartOf", noSideEffect.} magic: "IsPartOf", noSideEffect.}
## not yet exported properly. ## not yet exported properly.
template compileTimeAssert(cond: expr) = template compileTimeAssert(cond) =
when not cond: when not cond:
{.compile: "is false: " & astToStr(cond).} {.compile: "is false: " & astToStr(cond).}
template `<|` (a, b: expr) = template `<|` (a, b) =
compileTimeAssert isPartOf(a, b) == arYes compileTimeAssert isPartOf(a, b) == arYes
template `!<|` (a, b: expr) = template `!<|` (a, b) =
compileTimeAssert isPartOf(a, b) == arNo compileTimeAssert isPartOf(a, b) == arNo
template `?<|` (a, b: expr) = template `?<|` (a, b) =
compileTimeAssert isPartOf(a, b) == arMaybe compileTimeAssert isPartOf(a, b) == arMaybe
type type

View file

@ -2,7 +2,7 @@ discard """
output: "x == 45ugh" output: "x == 45ugh"
""" """
template myAssert(cond: expr) = template myAssert(cond: untyped) =
when 3 <= 3: when 3 <= 3:
let c = cond.astToStr let c = cond.astToStr
if not cond: if not cond:

View file

@ -2,7 +2,7 @@
var var
lastId = 0 lastId = 0
template genId*: expr = template genId*: int =
bind lastId bind lastId
inc(lastId) inc(lastId)
lastId lastId

View file

@ -6,7 +6,7 @@ discard """
proc p1(x: int8, y: int): int = return x + y proc p1(x: int8, y: int): int = return x + y
template tempBind(x, y: expr): expr = template tempBind(x, y): untyped =
bind p1 bind p1
p1(x, y) p1(x, y)

View file

@ -8,7 +8,7 @@ discard """
proc p1(x: int8, y: int): int = return x + y proc p1(x: int8, y: int): int = return x + y
proc p1(x: int, y: int8): int = return x - y proc p1(x: int, y: int8): int = return x - y
template tempBind(x, y: expr): expr = template tempBind(x, y): untyped =
(bind p1(x, y)) #ERROR_MSG ambiguous call (bind p1(x, y)) #ERROR_MSG ambiguous call
echo tempBind(1'i8, 2'i8) echo tempBind(1'i8, 2'i8)

View file

@ -1,7 +1,7 @@
# bug #1679 # bug #1679
import macros, tables, hashes import macros, tables, hashes
proc hash(v: NimNode): Hash = 4 # performance is for suckers proc hash(v: NimNode): Hash = 4 # performance is for suckers
macro test(body: stmt): stmt {.immediate.} = macro test(body: untyped): typed =
var a = initCountTable[NimNode]() var a = initCountTable[NimNode]()
a.inc(body) a.inc(body)

View file

@ -59,7 +59,7 @@ let
((1,1), hiA), ((1,1), hiA),
((0,1), hiB)] ((0,1), hiB)]
template odd*(i: int) : expr = template odd*(i: int) : untyped =
(i and 1) != 0 (i and 1) != 0
proc vidx(hg: HexGrid; col, row: int; i: HexVtxIndex) : Index = proc vidx(hg: HexGrid; col, row: int; i: HexVtxIndex) : Index =

View file

@ -2,109 +2,109 @@ import macros, strutils
# https://github.com/nim-lang/Nim/issues/1512 # https://github.com/nim-lang/Nim/issues/1512
proc macrobust0 (raw_input: string) = proc macrobust0(raw_input: string) =
var output = "" var output = ""
proc p1 (a:string) = proc p1(a:string) =
output.add (a) output.add(a)
proc p2 (a:string) = p1 (a) proc p2(a:string) = p1(a)
proc p3 (a:string) = p2 (a) proc p3(a:string) = p2(a)
proc p4 (a:string) = p3 (a) proc p4(a:string) = p3(a)
proc p5 (a:string) = p4 (a) proc p5(a:string) = p4(a)
proc p6 (a:string) = p5 (a) proc p6(a:string) = p5(a)
proc p7 (a:string) = p6 (a) proc p7(a:string) = p6(a)
proc p8 (a:string) = p7 (a) proc p8(a:string) = p7(a)
proc p9 (a:string) = p8 (a) proc p9(a:string) = p8(a)
proc p10 (a:string) = p9 (a) proc p10(a:string) = p9(a)
proc p11 (a:string) = p10 (a) proc p11(a:string) = p10(a)
proc p12 (a:string) = p11 (a) proc p12(a:string) = p11(a)
proc p13 (a:string) = p12 (a) proc p13(a:string) = p12(a)
proc p14 (a:string) = p13 (a) proc p14(a:string) = p13(a)
proc p15 (a:string) = p14 (a) proc p15(a:string) = p14(a)
proc p16 (a:string) = p15 (a) proc p16(a:string) = p15(a)
proc p17 (a:string) = p16 (a) proc p17(a:string) = p16(a)
proc p18 (a:string) = p17 (a) proc p18(a:string) = p17(a)
proc p19 (a:string) = p18 (a) proc p19(a:string) = p18(a)
proc p20 (a:string) = p19 (a) proc p20(a:string) = p19(a)
let input = $raw_input let input = $raw_input
for a in input.split (): for a in input.split():
p20 (a) p20(a)
p19 (a) p19(a)
p18 (a) p18(a)
p17 (a) p17(a)
p16 (a) p16(a)
p15 (a) p15(a)
p14 (a) p14(a)
p13 (a) p13(a)
p12 (a) p12(a)
p11 (a) p11(a)
p10 (a) p10(a)
p9 (a) p9(a)
p8 (a) p8(a)
p7 (a) p7(a)
p6 (a) p6(a)
p5 (a) p5(a)
p4 (a) p4(a)
p3 (a) p3(a)
p2 (a) p2(a)
p1 (a) p1(a)
echo output echo output
macro macrobust (raw_input: expr) : stmt = macro macrobust(raw_input: untyped): untyped =
var output = "" var output = ""
proc p1 (a:string) = proc p1(a:string) =
output.add (a) output.add(a)
proc p2 (a:string) = p1 (a) proc p2(a:string) = p1(a)
proc p3 (a:string) = p2 (a) proc p3(a:string) = p2(a)
proc p4 (a:string) = p3 (a) proc p4(a:string) = p3(a)
proc p5 (a:string) = p4 (a) proc p5(a:string) = p4(a)
proc p6 (a:string) = p5 (a) proc p6(a:string) = p5(a)
proc p7 (a:string) = p6 (a) proc p7(a:string) = p6(a)
proc p8 (a:string) = p7 (a) proc p8(a:string) = p7(a)
proc p9 (a:string) = p8 (a) proc p9(a:string) = p8(a)
proc p10 (a:string) = p9 (a) proc p10(a:string) = p9(a)
proc p11 (a:string) = p10 (a) proc p11(a:string) = p10(a)
proc p12 (a:string) = p11 (a) proc p12(a:string) = p11(a)
proc p13 (a:string) = p12 (a) proc p13(a:string) = p12(a)
proc p14 (a:string) = p13 (a) proc p14(a:string) = p13(a)
proc p15 (a:string) = p14 (a) proc p15(a:string) = p14(a)
proc p16 (a:string) = p15 (a) proc p16(a:string) = p15(a)
proc p17 (a:string) = p16 (a) proc p17(a:string) = p16(a)
proc p18 (a:string) = p17 (a) proc p18(a:string) = p17(a)
proc p19 (a:string) = p18 (a) proc p19(a:string) = p18(a)
proc p20 (a:string) = p19 (a) proc p20(a:string) = p19(a)
let input = $raw_input let input = $raw_input
for a in input.split (): for a in input.split():
p20 (a) p20(a)
p19 (a) p19(a)
p18 (a) p18(a)
p17 (a) p17(a)
p16 (a) p16(a)
p15 (a) p15(a)
p14 (a) p14(a)
p13 (a) p13(a)
p12 (a) p12(a)
p11 (a) p11(a)
p10 (a) p10(a)
p9 (a) p9(a)
p8 (a) p8(a)
p7 (a) p7(a)
p6 (a) p6(a)
p5 (a) p5(a)
p4 (a) p4(a)
p3 (a) p3(a)
p2 (a) p2(a)
echo output echo output
discard result discard result

View file

@ -1,6 +1,6 @@
# Test if the new table constructor syntax works: # Test if the new table constructor syntax works:
template ignoreExpr(e: expr): stmt {.immediate.} = template ignoreExpr(e) =
discard discard
# test first class '..' syntactical citizen: # test first class '..' syntactical citizen:

View file

@ -1,13 +1,15 @@
# test the new 'compiles' feature: # test the new 'compiles' feature:
template supports(opr, x: expr): bool {.immediate.} = template supports(opr, x: untyped): bool =
compiles(opr(x)) or compiles(opr(x, x)) compiles(opr(x)) or compiles(opr(x, x))
template ok(x: expr): stmt = template ok(x) =
static: assert(x) static:
assert(x)
template no(x: expr): stmt = template no(x) =
static: assert(not x) static:
assert(not x)
type type
TObj = object TObj = object

View file

@ -9,7 +9,6 @@ proc `[]=`*(M: var Matrix; m, n: int; v: M.T) =
M.data[m * M.N + n] = v M.data[m * M.N + n] = v
# Adapt the Matrix type to the concept's requirements # Adapt the Matrix type to the concept's requirements
template Rows*(M: type Matrix): expr = M.M template Rows*(M: type Matrix): untyped = M.M
template Cols*(M: type Matrix): expr = M.N template Cols*(M: type Matrix): untyped = M.N
template ValueType*(M: type Matrix): typedesc = M.T template ValueType*(M: type Matrix): typedesc = M.T

View file

@ -14,10 +14,10 @@ t
''' '''
""" """
template accept(e: expr) = template accept(e) =
static: assert compiles(e) static: assert compiles(e)
template reject(e: expr) = template reject(e) =
static: assert(not compiles(e)) static: assert(not compiles(e))
type type
@ -40,4 +40,3 @@ takesContainer(@[4, 5, 6])
takesContainer(@["a", "b"]) takesContainer(@["a", "b"])
takesContainer "test" takesContainer "test"
reject takesContainer(10) reject takesContainer(10)

View file

@ -12,7 +12,7 @@ IMPLICIT VALUE TYPE NAME INT INT
import typetraits, strutils import typetraits, strutils
template reject(e: expr) = template reject(e) =
static: assert(not compiles(e)) static: assert(not compiles(e))
type type
@ -60,4 +60,3 @@ reject s.genericAlgorithm "x"
reject s.genericAlgorithm 1.0 reject s.genericAlgorithm 1.0
reject "str".implicitGeneric reject "str".implicitGeneric
reject implicitGeneric(10) reject implicitGeneric(10)

View file

@ -13,7 +13,7 @@ q[float](0.8, 0.2)
# bug #942 # bug #942
template maybeMod(x: Tinteger, module:Natural):expr = template maybeMod(x: Tinteger, module:Natural): untyped =
if module > 0: x mod module if module > 0: x mod module
else: x else: x

View file

@ -10,7 +10,7 @@ A'''
# bug #1742 # bug #1742
template test(): expr = template test(): untyped =
let a = 0 let a = 0
defer: echo "hi" defer: echo "hi"
a a
@ -29,7 +29,7 @@ template atFuncEnd =
defer: defer:
echo "B" echo "B"
template testB(): expr = template testB(): untyped =
let a = 0 let a = 0
defer: echo "hi" # Delete this line to make it work defer: echo "hi" # Delete this line to make it work
a a

View file

@ -9,7 +9,7 @@ for name, value in (n: "v").fieldPairs:
echo name echo name
# This doesn't compile - "expression 'name' has no type (or is ambiguous)". # This doesn't compile - "expression 'name' has no type (or is ambiguous)".
template wrapper: stmt = template wrapper: typed =
for name, value in (n: "v").fieldPairs: for name, value in (n: "v").fieldPairs:
echo name echo name
wrapper() wrapper()

View file

@ -10,7 +10,7 @@ passed.'''
""" """
import strutils import strutils
template expect_fail(x: expr) = template expect_fail(x) =
try: try:
discard x discard x
echo("expected to fail!") echo("expected to fail!")

View file

@ -66,7 +66,7 @@ proc setItem[T,D](Akey: T, Avalue: D, ANode: PNode[T,D]): ref TItem[T,D] {.inlin
proc cmp[T:int8|int16|int32|int64|int] (a,b: T): T {.inline.} = proc cmp[T:int8|int16|int32|int64|int] (a,b: T): T {.inline.} =
return a-b return a-b
template binSearchImpl *(docmp: expr) {.immediate.} = template binSearchImpl *(docmp: untyped) =
var bFound = false var bFound = false
result = 0 result = 0
var H = haystack.len - 1 var H = haystack.len - 1

View file

@ -5,7 +5,7 @@ discard """
# bug #3498 # bug #3498
template defaultOf[T](t: T): expr = (var d: T; d) template defaultOf[T](t: T): untyped = (var d: T; d)
echo defaultOf(1) #<- excpected 0 echo defaultOf(1) #<- excpected 0

View file

@ -27,5 +27,5 @@ ttmpl[int] #<- crash case #3
# but still allow normal use of [] on non-generic templates # but still allow normal use of [] on non-generic templates
template tarr: expr = [1, 2, 3, 4] template tarr: untyped = [1, 2, 3, 4]
echo tarr[1] echo tarr[1]

View file

@ -36,7 +36,7 @@ proc derefExpr(exprRef: string): NimNode {.compileTime.} =
type Mapped[Input; predicate: static[string]] = object type Mapped[Input; predicate: static[string]] = object
input: Input input: Input
macro map(input, predicate: expr): expr = macro map(input, predicate: untyped): untyped =
let predicate = callsite()[2] let predicate = callsite()[2]
newNimNode(nnkObjConstr).add( newNimNode(nnkObjConstr).add(
newNimNode(nnkBracketExpr).add( newNimNode(nnkBracketExpr).add(
@ -47,7 +47,7 @@ macro map(input, predicate: expr): expr =
ident"input", input)) ident"input", input))
proc `[]`(m: Mapped, i: int): auto = proc `[]`(m: Mapped, i: int): auto =
macro buildResult: expr = macro buildResult: untyped =
newCall( newCall(
derefExpr(m.predicate), derefExpr(m.predicate),
newNimNode(nnkBracketExpr).add( newNimNode(nnkBracketExpr).add(

View file

@ -2,7 +2,7 @@ discard """
output: "123100" output: "123100"
""" """
template hygienic(val: expr) = template hygienic(val) =
var x = val var x = val
stdout.write x stdout.write x

View file

@ -11,17 +11,15 @@ var x = if 4 != 5:
else: else:
"no" "no"
macro mymacro(n: expr): stmt {.immediate.} = nil macro mymacro(n): untyped {.immediate.} =
discard
mymacro: mymacro:
echo "test" echo "test"
else: else:
echo "else part" echo "else part"
if 4 == 3: if 4 == 3:
echo "bug" echo "bug"
else: else:
echo "no bug" echo "no bug"

View file

@ -11,7 +11,7 @@ type
TTextKind = enum TTextKind = enum
TFoo, TBar TFoo, TBar
macro test: stmt = macro test: untyped =
var x = @[TFoo, TBar] var x = @[TFoo, TBar]
result = newStmtList() result = newStmtList()
for i in x: for i in x:

View file

@ -26,7 +26,7 @@ iterator test2(f: string): Foo =
for i in f: for i in f:
yield Foo(s: i) yield Foo(s: i)
macro test(): stmt = macro test(): untyped =
for i in test2("asdf"): for i in test2("asdf"):
echo i.s echo i.s
@ -39,7 +39,7 @@ import macros
type TType = tuple[s: string] type TType = tuple[s: string]
macro echotest(): stmt = macro echotest(): untyped =
var t: TType var t: TType
t.s = "" t.s = ""
t.s.add("test") t.s.add("test")
@ -61,7 +61,7 @@ proc get_data(d: Td) : string {.compileTime.} =
#result.add("aa") # B #result.add("aa") # B
#result = result & "aa" # C #result = result & "aa" # C
macro m(s:static[Td]) : stmt = macro m(s:static[Td]) : untyped =
echo get_data(s) echo get_data(s)
echo get_data(s) echo get_data(s)
result = newEmptyNode() result = newEmptyNode()
@ -77,7 +77,7 @@ proc nilcheck(): NimNode {.compileTime.} =
echo(result.isNil) # true echo(result.isNil) # true
echo(repr(result)) # nil echo(repr(result)) # nil
macro testnilcheck(): stmt = macro testnilcheck(): untyped =
result = newNimNode(nnkStmtList) result = newNimNode(nnkStmtList)
discard nilcheck() discard nilcheck()
@ -95,10 +95,10 @@ echo c[0]
# bug #3046 # bug #3046
macro sampleMacroInt(i: int): stmt = macro sampleMacroInt(i: int): untyped =
echo i.intVal echo i.intVal
macro sampleMacroBool(b: bool): stmt = macro sampleMacroBool(b: bool): untyped =
echo b.boolVal echo b.boolVal
sampleMacroInt(42) sampleMacroInt(42)

View file

@ -10,7 +10,7 @@ OK
import macros import macros
# Bug from the forum # Bug from the forum
macro addEcho1(s: untyped): stmt = macro addEcho1(s: untyped): untyped =
s.body.add(newCall("echo", newStrLitNode("OK"))) s.body.add(newCall("echo", newStrLitNode("OK")))
result = s result = s
@ -32,7 +32,7 @@ proc foo(): seq[NimNode] {.compiletime.} =
result.add test() result.add test()
result.add parseExpr("echo(5+56)") result.add parseExpr("echo(5+56)")
macro bar(): stmt = macro bar(): typed =
result = newNimNode(nnkStmtList) result = newNimNode(nnkStmtList)
let x = foo() let x = foo()
for xx in x: for xx in x:

View file

@ -6,7 +6,7 @@ x: some string'''
import macros import macros
macro debug(n: varargs[expr]): stmt = macro debug(n: varargs[untyped]): untyped =
# `n` is a Nim AST that contains the whole macro invocation # `n` is a Nim AST that contains the whole macro invocation
# this macro returns a list of statements: # this macro returns a list of statements:
result = newNimNode(nnkStmtList, n) result = newNimNode(nnkStmtList, n)

View file

@ -21,7 +21,7 @@ proc dumpit(n: NimNode): string {.compileTime.} =
add(result, dumpit(n[j])) add(result, dumpit(n[j]))
add(result, ")") add(result, ")")
macro dumpAST(n: stmt): stmt {.immediate.} = macro dumpAST(n): untyped =
# dump AST as a side-effect and return the inner node # dump AST as a side-effect and return the inner node
let n = callsite() let n = callsite()
echo dumpit(n) echo dumpit(n)

View file

@ -13,7 +13,7 @@ Infix
""" """
import macros import macros
macro def(x: stmt): stmt {.immediate.} = macro def(x): untyped =
echo treeRepr(x) echo treeRepr(x)
def name(a, b:cint) => nil def name(a, b:cint) => nil

View file

@ -11,7 +11,7 @@ proc convertReturns(node, retFutureSym: NimNode): NimNode {.compileTime.} =
for i in 0 .. <node.len: for i in 0 .. <node.len:
result[i] = convertReturns(node[i], retFutureSym) result[i] = convertReturns(node[i], retFutureSym)
macro async2(prc: stmt): stmt {.immediate.} = macro async2(prc: untyped): untyped =
expectKind(prc, nnkProcDef) expectKind(prc, nnkProcDef)
var outerProcBody = newNimNode(nnkStmtList) var outerProcBody = newNimNode(nnkStmtList)

View file

@ -20,7 +20,7 @@ proc parse_template(node: NimNode, value: string) {.compiletime.} =
while index < value.len and while index < value.len and
parse_until_symbol(node, value, index): discard parse_until_symbol(node, value, index): discard
macro tmpli*(body: expr): stmt = macro tmpli*(body: untyped): typed =
result = newStmtList() result = newStmtList()
result.add parseExpr("result = \"\"") result.add parseExpr("result = \"\"")
result.parse_template body[1].strVal result.parse_template body[1].strVal

View file

@ -10,11 +10,11 @@ type
name : string name : string
password : string password : string
macro testUser: expr = macro testUser: string =
return newLit(User.getType.lispRepr) result = newLit(User.getType.lispRepr)
macro testGeneric(T: typedesc[Model]): expr = macro testGeneric(T: typedesc[Model]): string=
return newLit(T.getType.lispRepr) result = newLit(T.getType.lispRepr)
echo testUser echo testUser
echo User.testGeneric echo User.testGeneric

View file

@ -22,7 +22,7 @@ proc symToIdent(x: NimNode): NimNode =
result.add symToIdent(c) result.add symToIdent(c)
# check getTypeInst and getTypeImpl for given symbol x # check getTypeInst and getTypeImpl for given symbol x
macro testX(x,inst0: typed; recurse: static[bool]; implX: stmt): typed = macro testX(x,inst0: typed; recurse: static[bool]; implX: typed): typed =
# check that getTypeInst(x) equals inst0 # check that getTypeInst(x) equals inst0
let inst = x.getTypeInst let inst = x.getTypeInst
let instr = inst.symToIdent.treeRepr let instr = inst.symToIdent.treeRepr

View file

@ -8,7 +8,7 @@ import macros
var gid {.compileTime.} = 3 var gid {.compileTime.} = 3
macro genId(): expr = macro genId(): int =
result = newIntLitNode(gid) result = newIntLitNode(gid)
inc gid inc gid

View file

@ -2,7 +2,7 @@ import macros
from uri import `/` from uri import `/`
macro test*(a: stmt): stmt {.immediate.} = macro test*(a: untyped): untyped =
var nodes: tuple[a, b: int] var nodes: tuple[a, b: int]
nodes.a = 4 nodes.a = 4
nodes[1] = 45 nodes[1] = 45
@ -20,4 +20,3 @@ macro test*(a: stmt): stmt {.immediate.} =
test: test:
"hi" "hi"

View file

@ -12,7 +12,7 @@ proc testBlock(): string {.compileTime.} =
echo "outer block" echo "outer block"
result = "ta-da" result = "ta-da"
macro mac(n: expr): expr = macro mac(n: typed): string =
let n = callsite() let n = callsite()
expectKind(n, nnkCall) expectKind(n, nnkCall)
expectLen(n, 2) expectLen(n, 2)

View file

@ -8,7 +8,7 @@ type
TA = tuple[a: int] TA = tuple[a: int]
PA = ref TA PA = ref TA
macro test*(a: stmt): stmt {.immediate.} = macro test*(a: untyped): untyped =
var val: PA var val: PA
new(val) new(val)
val.a = 4 val.a = 4
@ -16,7 +16,7 @@ macro test*(a: stmt): stmt {.immediate.} =
test: test:
"hi" "hi"
macro test2*(a: stmt): stmt {.immediate.} = macro test2*(a: untyped): untyped =
proc testproc(recurse: int) = proc testproc(recurse: int) =
echo "Thats weird" echo "Thats weird"
var o : NimNode = nil var o : NimNode = nil
@ -28,4 +28,3 @@ macro test2*(a: stmt): stmt {.immediate.} =
test2: test2:
"hi" "hi"

View file

@ -5,7 +5,7 @@ discard """
import import
macros, strutils macros, strutils
macro test_macro*(s: string, n: stmt): stmt {.immediate.} = macro test_macro*(s: string, n: untyped): untyped =
result = newNimNode(nnkStmtList) result = newNimNode(nnkStmtList)
var ass : NimNode = newNimNode(nnkAsgn) var ass : NimNode = newNimNode(nnkAsgn)
add(ass, newIdentNode("str")) add(ass, newIdentNode("str"))
@ -16,4 +16,3 @@ when isMainModule:
test_macro(str): test_macro(str):
var i : integer = 123 var i : integer = 123
echo str echo str

View file

@ -3,7 +3,7 @@ import macros,json
var decls{.compileTime.}: seq[NimNode] = @[] var decls{.compileTime.}: seq[NimNode] = @[]
var impls{.compileTime.}: seq[NimNode] = @[] var impls{.compileTime.}: seq[NimNode] = @[]
macro importImpl_forward(name, returns): stmt {.immediate.} = macro importImpl_forward(name, returns: untyped): untyped =
result = newNimNode(nnkEmpty) result = newNimNode(nnkEmpty)
var func_name = newNimNode(nnkAccQuoted) var func_name = newNimNode(nnkAccQuoted)
func_name.add newIdentNode("import") func_name.add newIdentNode("import")
@ -19,7 +19,7 @@ macro importImpl_forward(name, returns): stmt {.immediate.} =
res[3].add returns res[3].add returns
var p1 = newNimNode(nnkIdentDefs) var p1 = newNimNode(nnkIdentDefs)
p1.add newIdentNode("dat") p1.add newIdentNode("dat")
p1.add newIdentNOde("PJsonNode") p1.add newIdentNOde("JsonNode")
p1.add newNimNode(nnkEmpty) p1.add newNimNode(nnkEmpty)
res[3].add p1 res[3].add p1
var p2 = newNimNode(nnkIdentDefs) var p2 = newNimNode(nnkIdentDefs)
@ -38,7 +38,7 @@ macro importImpl_forward(name, returns): stmt {.immediate.} =
decls.add res decls.add res
echo(repr(res)) echo(repr(res))
macro importImpl(name, returns: expr, body: stmt): stmt {.immediate.} = macro importImpl(name, returns, body: untyped): typed =
#var res = getAST(importImpl_forward(name, returns)) #var res = getAST(importImpl_forward(name, returns))
discard getAST(importImpl_forward(name, returns)) discard getAST(importImpl_forward(name, returns))
var res = copyNimTree(decls[decls.high]) var res = copyNimTree(decls[decls.high])
@ -46,7 +46,7 @@ macro importImpl(name, returns: expr, body: stmt): stmt {.immediate.} =
echo repr(res) echo repr(res)
impls.add res impls.add res
macro okayy:stmt = macro okayy: typed =
result = newNimNode(nnkStmtList) result = newNimNode(nnkStmtList)
for node in decls: result.add node for node in decls: result.add node
for node in impls: result.add node for node in impls: result.add node

View file

@ -2,8 +2,8 @@
# bug #1944 # bug #1944
import macros import macros
template t(e: expr): stmt = template t(e: untyped): untyped =
macro m(eNode: expr): stmt = macro m(eNode: untyped): untyped =
echo eNode.treeRepr echo eNode.treeRepr
m e m e

View file

@ -1,8 +1,7 @@
import macros import macros
macro foo(x: stmt): stmt = macro foo(x: untyped): untyped =
echo treerepr(callsite()) echo treerepr(callsite())
result = newNimNode(nnkStmtList) result = newNimNode(nnkStmtList)
proc zoo() {.foo.} = echo "hi" proc zoo() {.foo.} = echo "hi"

View file

@ -5,7 +5,7 @@ discard """
import import
macros, strutils macros, strutils
macro outterMacro*(n: stmt): stmt {.immediate.} = macro outterMacro*(n, blck: untyped): untyped =
let n = callsite() let n = callsite()
var j : string = "hi" var j : string = "hi"
proc innerProc(i: int): string = proc innerProc(i: int): string =
@ -27,5 +27,3 @@ var str: string
outterMacro(str): outterMacro(str):
"hellow" "hellow"
echo str echo str

View file

@ -1,5 +1,5 @@
import macros import macros
macro case_token(n: stmt): stmt {.immediate.} = macro case_token(n: untyped): untyped {.immediate.} =
# creates a lexical analyzer from regular expressions # creates a lexical analyzer from regular expressions
# ... (implementation is an exercise for the reader :-) # ... (implementation is an exercise for the reader :-)
nil nil
@ -18,7 +18,7 @@ case_token: inc i
#bug #488 #bug #488
macro foo: stmt = macro foo: typed =
var exp = newCall("whatwhat", newIntLitNode(1)) var exp = newCall("whatwhat", newIntLitNode(1))
if compiles(getAst(exp)): return exp if compiles(getAst(exp)): return exp
else: echo "Does not compute!" else: echo "Does not compute!"

View file

@ -5,7 +5,7 @@ int'''
import macros import macros
macro checkType(ex: stmt; expected: expr): stmt = macro checkType(ex: typed; expected: string): untyped =
var t = ex.getType() var t = ex.getType()
echo t echo t

View file

@ -11,7 +11,7 @@ static:
nodeB.strVal = "this is a different comment" nodeB.strVal = "this is a different comment"
doAssert nodeA != nodeB doAssert nodeA != nodeB
macro test(a: typed, b: typed): expr = macro test(a: typed, b: typed): untyped =
newLit(a == b) newLit(a == b)
doAssert test(1, 1) == true doAssert test(1, 1) == true
@ -29,10 +29,10 @@ var a, b: int
doAssert test(a, a) == true doAssert test(a, a) == true
doAssert test(a, b) == false doAssert test(a, b) == false
macro test2: expr = macro test2: untyped =
newLit(bindSym"Obj" == bindSym"Obj") newLit(bindSym"Obj" == bindSym"Obj")
macro test3: expr = macro test3: untyped =
newLit(bindSym"Obj" == bindSym"Other") newLit(bindSym"Obj" == bindSym"Other")
doAssert test2() == true doAssert test2() == true

View file

@ -6,7 +6,7 @@ discard """
import macros import macros
macro quoteWords(n: varargs[expr]): expr {.immediate.} = macro quoteWords(n: varargs[untyped]): untyped =
let n = callsite() let n = callsite()
result = newNimNode(nnkBracket, n) result = newNimNode(nnkBracket, n)
for i in 1..n.len-1: for i in 1..n.len-1:
@ -21,6 +21,3 @@ for w in items(myWordList):
s.add(w) s.add(w)
echo s #OUT thisanexample echo s #OUT thisanexample

View file

@ -4,7 +4,7 @@ discard """
errormsg: "recursive dependency: 'dump'" errormsg: "recursive dependency: 'dump'"
""" """
macro dump(n: stmt): stmt = macro dump(n: untyped): untyped =
dump(n) dump(n)
if kind(n) == nnkNone: if kind(n) == nnkNone:
nil nil

View file

@ -3,10 +3,9 @@ discard """
line: 11 line: 11
""" """
# bug #2372 # bug #2372
macro foo(dummy: int): stmt = macro foo(dummy: int): untyped =
discard discard
proc takeStr(s: string) = echo s proc takeStr(s: string) = echo s
takeStr foo(12) takeStr foo(12)

View file

@ -13,7 +13,7 @@ false'''
import macros import macros
macro same(a: typedesc, b: typedesc): expr = macro same(a: typedesc, b: typedesc): untyped =
newLit(a.getType[1].sameType b.getType[1]) newLit(a.getType[1].sameType b.getType[1])
echo same(int, int) echo same(int, int)

View file

@ -25,7 +25,7 @@ type
const data: Tconfig = (@["aa", "bb"], @[11, 22]) const data: Tconfig = (@["aa", "bb"], @[11, 22])
macro mymacro(data: static[TConfig]): stmt = macro mymacro(data: static[TConfig]): untyped =
echo "letters" echo "letters"
for s in items(data.letters): for s in items(data.letters):
echo s echo s
@ -43,10 +43,10 @@ const
a : Ta = @[(11, 22), (33, 44)] a : Ta = @[(11, 22), (33, 44)]
b : Tb = (@[55,66], @[77, 88]) b : Tb = (@[55,66], @[77, 88])
macro mA(data: static[Ta]): stmt = macro mA(data: static[Ta]): untyped =
echo "AST a \n", repr(data) echo "AST a \n", repr(data)
macro mB(data: static[Tb]): stmt = macro mB(data: static[Tb]): untyped =
echo "AST b \n", repr(data) echo "AST b \n", repr(data)
echo data.e[0] echo data.e[0]
@ -56,13 +56,13 @@ mB(b)
type type
Foo[N: static[int], Z: static[string]] = object Foo[N: static[int], Z: static[string]] = object
macro staticIntMacro(f: static[int]): stmt = echo f macro staticIntMacro(f: static[int]): untyped = echo f
staticIntMacro 10 staticIntMacro 10
var var
x: Foo[20, "Test"] x: Foo[20, "Test"]
macro genericMacro[N; Z: static[string]](f: Foo[N, Z], ll = 3, zz = 12): stmt = macro genericMacro[N; Z: static[string]](f: Foo[N, Z], ll = 3, zz = 12): untyped =
echo N, Z echo N, Z
genericMacro x genericMacro x

View file

@ -9,7 +9,7 @@ proc concat(strings: varargs[string]): string =
result = newString(0) result = newString(0)
for s in items(strings): result.add(s) for s in items(strings): result.add(s)
template processInterpolations(e: expr) = template processInterpolations(e) =
var s = e[1].strVal var s = e[1].strVal
for f in interpolatedFragments(s): for f in interpolatedFragments(s):
case f.kind case f.kind
@ -17,7 +17,7 @@ template processInterpolations(e: expr) =
of ikDollar: addDollar() of ikDollar: addDollar()
of ikVar, ikExpr: addExpr(newCall("$", parseExpr(f.value))) of ikVar, ikExpr: addExpr(newCall("$", parseExpr(f.value)))
macro formatStyleInterpolation(e: expr): expr = macro formatStyleInterpolation(e: untyped): untyped =
let e = callsite() let e = callsite()
var var
formatString = "" formatString = ""
@ -41,7 +41,7 @@ macro formatStyleInterpolation(e: expr): expr =
result[1].strVal = formatString result[1].strVal = formatString
result[2] = arrayNode result[2] = arrayNode
macro concatStyleInterpolation(e: expr): expr = macro concatStyleInterpolation(e: untyped): untyped =
let e = callsite() let e = callsite()
var args: seq[NimNode] var args: seq[NimNode]
newSeq(args, 0) newSeq(args, 0)
@ -71,4 +71,3 @@ var
s2 = formatStyleInterpolation"Hello ${bob}, ${sum(alice.len, bob.len, 2)}$$" s2 = formatStyleInterpolation"Hello ${bob}, ${sum(alice.len, bob.len, 2)}$$"
write(stdout, s1 & " | " & s2) write(stdout, s1 & " | " & s2)

View file

@ -5,7 +5,7 @@ discard """
# feature request #1473 # feature request #1473
import macros import macros
macro test(text: string): expr = macro test(text: string): untyped =
try: try:
result = parseExpr(text.strVal) result = parseExpr(text.strVal)
except ValueError: except ValueError:

View file

@ -10,7 +10,7 @@ proc test(f: var NimNode) {.compileTime.} =
f = newNimNode(nnkStmtList) f = newNimNode(nnkStmtList)
f.add newCall(newIdentNode("echo"), newLit(10)) f.add newCall(newIdentNode("echo"), newLit(10))
macro blah(prc: stmt): stmt = macro blah(prc: untyped): untyped =
result = prc result = prc
test(result) test(result)

View file

@ -8,7 +8,7 @@ proc (x: int) => typeDesc[proc[void, int]]'''
import macros import macros
macro showType(t:stmt): stmt = macro showType(t:typed): untyped =
let ty = t.getType let ty = t.getType
echo t.repr, " => ", ty.repr echo t.repr, " => ", ty.repr

View file

@ -2,7 +2,7 @@
# be used as a type # be used as a type
import macros import macros
macro testTypesym (t:stmt): expr = macro testTypesym (t:typed): untyped =
var ty = t.getType var ty = t.getType
if ty.typekind == ntyTypedesc: if ty.typekind == ntyTypedesc:
# skip typedesc get to the real type # skip typedesc get to the real type
@ -31,7 +31,7 @@ static: assert(ref int is testTypesym(ref int))
static: assert(void is testTypesym(void)) static: assert(void is testTypesym(void))
macro tts2 (t:stmt, idx:int): expr = macro tts2 (t:typed, idx:int): untyped =
var ty = t.getType var ty = t.getType
if ty.typekind == ntyTypedesc: if ty.typekind == ntyTypedesc:
# skip typedesc get to the real type # skip typedesc get to the real type
@ -46,4 +46,3 @@ static:
assert(tts2(TestFN2, 1) is string) assert(tts2(TestFN2, 1) is string)
assert(tts2(TestFN2, 2) is int) assert(tts2(TestFN2, 2) is int)
assert(tts2(TestFN2, 3) is float) assert(tts2(TestFN2, 3) is float)

View file

@ -212,9 +212,10 @@ proc free(obj: PLiveBullet) =
obj.record = nil obj.record = nil
template newExplosion(obj, animation): stmt = template newExplosion(obj, animation) =
explosions.add(newAnimation(animation, AnimOnce, obj.body.getPos.cp2sfml, obj.body.getAngle)) explosions.add(newAnimation(animation, AnimOnce, obj.body.getPos.cp2sfml, obj.body.getAngle))
template newExplosion(obj, animation, angle): stmt =
template newExplosion(obj, animation, angle) =
explosions.add(newAnimation(animation, AnimOnce, obj.body.getPos.cp2sfml, angle)) explosions.add(newAnimation(animation, AnimOnce, obj.body.getPos.cp2sfml, angle))
proc explode*(b: PLiveBullet) = proc explode*(b: PLiveBullet) =

View file

@ -16,10 +16,10 @@ type
TBar = tuple TBar = tuple
x, y: int x, y: int
template accept(e: expr) = template accept(e) =
static: assert(compiles(e)) static: assert(compiles(e))
template reject(e: expr) = template reject(e) =
static: assert(not compiles(e)) static: assert(not compiles(e))
proc genericParamRepeated[T: typedesc](a: T, b: T) = proc genericParamRepeated[T: typedesc](a: T, b: T) =

View file

@ -9,7 +9,7 @@ type
data: seq[float] data: seq[float]
fWidth, fHeight: int fWidth, fHeight: int
template `|`(x, y: int): expr = y * m.fWidth + x template `|`(x, y: int): untyped = y * m.fWidth + x
proc createMatrix*(width, height: int): TMatrix = proc createMatrix*(width, height: int): TMatrix =
result.fWidth = width result.fWidth = width

View file

@ -7,7 +7,7 @@ type
semistatic[T] = semistatic[T] =
static[T] or T static[T] or T
template isStatic*(x): expr = template isStatic*(x): bool =
compiles(static(x)) compiles(static(x))
proc foo(x: semistatic[int]) = proc foo(x: semistatic[int]) =

View file

@ -5,6 +5,6 @@ import macros
proc impl(op: static[int]) = echo "impl 1 called" proc impl(op: static[int]) = echo "impl 1 called"
proc impl(op: static[int], init: int) = echo "impl 2 called" proc impl(op: static[int], init: int) = echo "impl 2 called"
macro wrapper2: stmt = newCall(bindSym"impl", newLit(0), newLit(0)) macro wrapper2: untyped = newCall(bindSym"impl", newLit(0), newLit(0))
wrapper2() # Code generation for this fails. wrapper2() # Code generation for this fails.

View file

@ -26,7 +26,7 @@ type
const data: Tconfig = (@["aa", "bb"], @[11, 22]) const data: Tconfig = (@["aa", "bb"], @[11, 22])
macro mymacro(data: static[TConfig]): stmt = macro mymacro(data: static[TConfig]) =
echo "letters" echo "letters"
for s in items(data.letters): for s in items(data.letters):
echo s echo s
@ -44,10 +44,10 @@ const
a : Ta = @[(11, 22), (33, 44)] a : Ta = @[(11, 22), (33, 44)]
b : Tb = (@[55,66], @[77, 88]) b : Tb = (@[55,66], @[77, 88])
macro mA(data: static[Ta]): stmt = macro mA(data: static[Ta]) =
echo "AST a \n", repr(data) echo "AST a \n", repr(data)
macro mB(data: static[Tb]): stmt = macro mB(data: static[Tb]) =
echo "AST b \n", repr(data) echo "AST b \n", repr(data)
echo data.e[0] echo data.e[0]
@ -57,13 +57,13 @@ mB(b)
type type
Foo[N: static[int], Z: static[string]] = object Foo[N: static[int], Z: static[string]] = object
macro staticIntMacro(f: static[int]): stmt = echo f macro staticIntMacro(f: static[int]) = echo f
staticIntMacro 10 staticIntMacro 10
var var
x: Foo[20, "Test"] x: Foo[20, "Test"]
macro genericMacro[N; Z: static[string]](f: Foo[N, Z], ll = 3, zz = 12): stmt = macro genericMacro[N; Z: static[string]](f: Foo[N, Z], ll = 3, zz = 12) =
echo N, Z echo N, Z
genericMacro x genericMacro x

View file

@ -74,7 +74,7 @@ matrix_2(tmat, ar2)
matrix_3(tmat, ar1) matrix_3(tmat, ar1)
matrix_4(tmat, ar2) matrix_4(tmat, ar2)
template reject(x): stmt = template reject(x): untyped =
static: assert(not compiles(x)) static: assert(not compiles(x))
# test with arrays of wrong size # test with arrays of wrong size

View file

@ -18,7 +18,7 @@ proc foo(T: typedesc[int or bool]): string =
a = 10 a = 10
result = "int or bool " & ($a) result = "int or bool " & ($a)
template foo(T: typedesc[seq]): expr = "seq" template foo(T: typedesc[seq]): string = "seq"
test "types can be used as proc params": test "types can be used as proc params":
# XXX: `check` needs to know that TFoo[int, float] is a type and # XXX: `check` needs to know that TFoo[int, float] is a type and

View file

@ -1,6 +1,6 @@
import typetraits import typetraits
template reject(e: expr) = template reject(e) =
static: assert(not compiles(e)) static: assert(not compiles(e))
type type

View file

@ -15,7 +15,7 @@ proc fac[T](x: T): T =
if x <= 1: return 1 if x <= 1: return 1
else: return x.`*`(fac(x-1)) else: return x.`*`(fac(x-1))
macro macrotest(n: expr): stmt {.immediate.} = macro macrotest(n: varargs[untyped]): untyped =
let n = callsite() let n = callsite()
expectKind(n, nnkCall) expectKind(n, nnkCall)
expectMinLen(n, 2) expectMinLen(n, 2)
@ -24,7 +24,7 @@ macro macrotest(n: expr): stmt {.immediate.} =
result.add(newCall("write", n[1], n[i])) result.add(newCall("write", n[1], n[i]))
result.add(newCall("writeLine", n[1], newStrLitNode(""))) result.add(newCall("writeLine", n[1], newStrLitNode("")))
macro debug(n: expr): stmt {.immediate.} = macro debug(n: untyped): untyped {.immediate.} =
let n = callsite() let n = callsite()
result = newNimNode(nnkStmtList, n) result = newNimNode(nnkStmtList, n)
for i in 1..n.len-1: for i in 1..n.len-1:
@ -82,4 +82,3 @@ for i in 2..6:
when isMainModule: when isMainModule:
{.hint: "this is the main file".} {.hint: "this is the main file".}

View file

@ -8,7 +8,7 @@ Success'''
var testNumber = 0 var testNumber = 0
template test(opr, a, b, c: expr): stmt {.immediate.} = template test(opr, a, b, c: untyped): untyped =
# test the expression at compile and runtime # test the expression at compile and runtime
block: block:
const constExpr = opr(a, b) const constExpr = opr(a, b)

View file

@ -118,7 +118,7 @@ proc toTable*[A, B](pairs: openarray[tuple[key: A,
result = initTable[A, B](nextPowerOfTwo(pairs.len+10)) result = initTable[A, B](nextPowerOfTwo(pairs.len+10))
for key, val in items(pairs): result[key] = val for key, val in items(pairs): result[key] = val
template dollarImpl(): stmt = template dollarImpl(): typed =
if t.len == 0: if t.len == 0:
result = "{:}" result = "{:}"
else: else:
@ -305,5 +305,3 @@ proc countTableTest1 =
countTableTest1() countTableTest1()
echo true echo true

View file

@ -35,7 +35,7 @@ proc init(my: var TRectangle) =
my.height = 10 my.height = 10
my.draw = cast[proc (my: var TFigure) {.nimcall.}](drawRectangle) my.draw = cast[proc (my: var TFigure) {.nimcall.}](drawRectangle)
macro `!` (n: expr): stmt {.immediate.} = macro `!` (n: untyped): typed {.immediate.}=
let n = callsite() let n = callsite()
result = newNimNode(nnkCall, n) result = newNimNode(nnkCall, n)
var dot = newNimNode(nnkDotExpr, n) var dot = newNimNode(nnkDotExpr, n)

View file

@ -1,7 +1,8 @@
discard """ discard """
output: '''a 1 b 2 x @[3, 4, 5] y 6 z 7 output: '''a 1 b 2 x @[3, 4, 5] y 6 z 7
yay yay
12''' 12
'''
""" """
proc test(a, b: int, x: varargs[int]; y, z: int) = proc test(a, b: int, x: varargs[int]; y, z: int) =
@ -9,9 +10,10 @@ proc test(a, b: int, x: varargs[int]; y, z: int) =
test 1, 2, 3, 4, 5, 6, 7 test 1, 2, 3, 4, 5, 6, 7
template takesBlock(a, b: int, x: varargs[expr]; blck: stmt) = # XXX maybe this should also work with ``varargs[untyped]``
template takesBlockA(a, b: untyped; x: varargs[typed]; blck: untyped): untyped =
blck blck
echo a, b echo a, b
takesBlock 1, 2, "some", 0.90, "random stuff": takesBlockA 1, 2, "some", 0.90, "random stuff":
echo "yay" echo "yay"

Some files were not shown because too many files have changed in this diff Show more