From ebba9f06ae3074255830128ecb599fb22a3310ef Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Thu, 13 Jul 2017 04:43:53 +0200 Subject: fixes #5871 --- lib/system.nim | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/system.nim') diff --git a/lib/system.nim b/lib/system.nim index 424d9694d..8f653c1e0 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -442,6 +442,7 @@ type ## providing an exception message ## is bad style. trace: string + up: ref Exception # used for stacking exceptions. Not exported! SystemError* = object of Exception ## \ ## Abstract class for exceptions that the runtime system raises. -- cgit 1.4.1-2-gfad0 From ad608838bf8c6300cb0c62338c4e95c8d2afbeec Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Sat, 22 Jul 2017 11:10:44 +0200 Subject: closures have an object type field so that we can perform correct deepCopy() for the BoehmGC target --- compiler/ccgstmts.nim | 6 +++--- compiler/ccgtypes.nim | 4 +++- compiler/lambdalifting.nim | 2 +- compiler/lowerings.nim | 20 +++++++++++--------- lib/system.nim | 4 ++-- lib/system/deepcopy.nim | 6 +++--- tests/closure/tboehmdeepcopy.nim | 17 +++++++++++++++++ 7 files changed, 40 insertions(+), 19 deletions(-) create mode 100644 tests/closure/tboehmdeepcopy.nim (limited to 'lib/system.nim') diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 378951d9d..8796dd729 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -164,11 +164,11 @@ proc genBreakState(p: BProc, n: PNode) = if n.sons[0].kind == nkClosure: # XXX this produces quite inefficient code! initLocExpr(p, n.sons[0].sons[1], a) - lineF(p, cpsStmts, "if (((NI*) $1)[0] < 0) break;$n", [rdLoc(a)]) + lineF(p, cpsStmts, "if (((NI*) $1)[1] < 0) break;$n", [rdLoc(a)]) else: initLocExpr(p, n.sons[0], a) - # the environment is guaranteed to contain the 'state' field at offset 0: - lineF(p, cpsStmts, "if ((((NI*) $1.ClE_0)[0]) < 0) break;$n", [rdLoc(a)]) + # the environment is guaranteed to contain the 'state' field at offset 1: + lineF(p, cpsStmts, "if ((((NI*) $1.ClE_0)[1]) < 0) break;$n", [rdLoc(a)]) # lineF(p, cpsStmts, "if (($1) < 0) break;$n", [rdLoc(a)]) proc genVarPrototypeAux(m: BModule, sym: PSym) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index aba9c5342..322021287 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -12,6 +12,7 @@ # ------------------------- Name Mangling -------------------------------- import sighashes +from lowerings import createObj proc isKeyword(w: PIdent): bool = # Nim and C++ share some keywords @@ -1092,7 +1093,8 @@ proc fakeClosureType(owner: PSym): PType = result = newType(tyTuple, owner) result.rawAddSon(newType(tyPointer, owner)) var r = newType(tyRef, owner) - r.rawAddSon(newType(tyTuple, owner)) + let obj = createObj(owner, owner.info, final=false) + r.rawAddSon(obj) result.rawAddSon(r) type diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index cd2ccfe53..986d8c716 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -142,7 +142,7 @@ proc createStateField(iter: PSym): PSym = proc createEnvObj(owner: PSym; info: TLineInfo): PType = # YYY meh, just add the state field for every closure for now, it's too # hard to figure out if it comes from a closure iterator: - result = createObj(owner, info) + result = createObj(owner, info, final=false) rawAddField(result, createStateField(owner)) proc getIterResult(iter: PSym): PSym = diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index 4bd54603d..ce76b63a4 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -109,17 +109,19 @@ proc lowerSwap*(n: PNode; owner: PSym): PNode = result.add newFastAsgnStmt(n[1], n[2]) result.add newFastAsgnStmt(n[2], tempAsNode) -proc createObj*(owner: PSym, info: TLineInfo): PType = +proc createObj*(owner: PSym, info: TLineInfo; final=true): PType = result = newType(tyObject, owner) - rawAddSon(result, nil) - incl result.flags, tfFinal + if final: + rawAddSon(result, nil) + incl result.flags, tfFinal + else: + rawAddSon(result, getCompilerProc("RootObj").typ) result.n = newNodeI(nkRecList, info) - when true: - let s = newSym(skType, getIdent("Env_" & info.toFilename), - owner, info) - incl s.flags, sfAnon - s.typ = result - result.sym = s + let s = newSym(skType, getIdent("Env_" & info.toFilename), + owner, info) + incl s.flags, sfAnon + s.typ = result + result.sym = s proc rawAddField*(obj: PType; field: PSym) = assert field.kind == skField diff --git a/lib/system.nim b/lib/system.nim index 8f653c1e0..d62c0424e 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -413,7 +413,7 @@ type ## is an int type ranging from one to the maximum value ## of an int. This type is often useful for documentation and debugging. - RootObj* {.exportc: "TNimObject", inheritable.} = + RootObj* {.compilerProc, inheritable.} = object ## the root of Nim's object hierarchy. Objects should ## inherit from RootObj or one of its descendants. However, ## objects that have no ancestor are allowed. @@ -3269,7 +3269,7 @@ when not defined(JS): #and not defined(nimscript): proc finished*[T: proc](x: T): bool {.noSideEffect, inline.} = ## can be used to determine if a first class iterator has finished. {.emit: """ - `result` = *((NI*) `x`.ClE_0) < 0; + `result` = ((NI*) `x`.ClE_0)[1] < 0; """.} elif defined(JS): diff --git a/lib/system/deepcopy.nim b/lib/system/deepcopy.nim index e12f08842..65ba2278c 100644 --- a/lib/system/deepcopy.nim +++ b/lib/system/deepcopy.nim @@ -148,11 +148,11 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) = let realType = x.typ sysAssert realType == mt, " types do differ" # this version should work for any possible GC: - let size = if mt.base.kind == tyObject: cast[ptr PNimType](s2)[].size else: mt.base.size - let z = newObj(mt, size) + let typ = if mt.base.kind == tyObject: cast[ptr PNimType](s2)[] else: mt.base + let z = newObj(mt, typ.size) unsureAsgnRef(cast[PPointer](dest), z) tab.put(s2, z) - genericDeepCopyAux(z, s2, mt.base, tab) + genericDeepCopyAux(z, s2, typ, tab) else: unsureAsgnRef(cast[PPointer](dest), z) of tyPtr: diff --git a/tests/closure/tboehmdeepcopy.nim b/tests/closure/tboehmdeepcopy.nim new file mode 100644 index 000000000..79ac5797a --- /dev/null +++ b/tests/closure/tboehmdeepcopy.nim @@ -0,0 +1,17 @@ +discard """ + cmd: "nim c --gc:boehm $options $file" + output: '''meep''' +""" + +proc callit(it: proc ()) = + it() + +proc main = + var outer = "meep" + proc x = + echo outer + var y: proc() + deepCopy(y, x) + callit(y) + +main() -- cgit 1.4.1-2-gfad0 From 000b8afd26fa16684a116d9afe798ea94df9c270 Mon Sep 17 00:00:00 2001 From: Arne Döring Date: Tue, 25 Jul 2017 09:28:23 +0200 Subject: Remove expr/stmt (#5857) --- compiler/evalffi.nim | 16 +-- compiler/semtempl.nim | 4 +- compiler/testability.nim | 5 - examples/allany.nim | 4 +- lib/core/typeinfo.nim | 2 +- lib/deprecated/pure/sockets.nim | 33 +++-- lib/impure/nre/private/util.nim | 2 +- lib/packages/docutils/rstgen.nim | 4 +- lib/posix/termios.nim | 2 +- lib/pure/asyncdispatch.nim | 2 +- lib/pure/asyncnet.nim | 4 +- lib/pure/basic2d.nim | 6 +- lib/pure/basic3d.nim | 4 +- lib/pure/collections/critbits.nim | 7 +- lib/pure/collections/intsets.nim | 2 +- lib/pure/collections/sequtils.nim | 2 +- lib/pure/collections/sharedtables.nim | 2 +- lib/pure/collections/tableimpl.nim | 4 +- lib/pure/colors.nim | 12 +- lib/pure/concurrency/threadpool.nim | 8 +- lib/pure/memfiles.nim | 6 +- lib/pure/net.nim | 2 +- lib/pure/pegs.nim | 22 ++-- lib/pure/subexes.nim | 4 +- lib/pure/terminal.nim | 11 +- lib/pure/uri.nim | 2 +- lib/pure/xmltree.nim | 2 +- lib/system.nim | 35 ++--- lib/system/channels.nim | 4 +- lib/system/excpt.nim | 7 +- lib/system/threads.nim | 2 +- tests/alias/talias.nim | 8 +- tests/assert/tuserassert.nim | 2 +- tests/bind/mbind3.nim | 2 +- tests/bind/tbind1.nim | 2 +- tests/bind/tbind2.nim | 2 +- tests/ccgbugs/tnocodegen_for_compiletime.nim | 2 +- tests/ccgbugs/tuple_canon.nim | 2 +- tests/closure/tmacrobust1512.nim | 182 +++++++++++++------------- tests/collections/ttableconstr.nim | 2 +- tests/compiles/tcompiles.nim | 12 +- tests/concepts/matrix.nim | 5 +- tests/concepts/tmanual.nim | 5 +- tests/concepts/tstackconcept.nim | 3 +- tests/discard/tdiscardable.nim | 2 +- tests/exception/tdefer1.nim | 4 +- tests/fields/tfields_in_template.nim | 2 +- tests/float/tfloat7.nim | 2 +- tests/generics/tgeneric3.nim | 2 +- tests/generics/tgenerictmpl.nim | 2 +- tests/generics/tgenerictmpl2.nim | 2 +- tests/generics/tunique_type.nim | 4 +- tests/gensym/tgensym.nim | 2 +- tests/lexer/tind1.nim | 6 +- tests/macros/tbindsym.nim | 2 +- tests/macros/tbugs.nim | 12 +- tests/macros/tcomplexecho.nim | 4 +- tests/macros/tdebugstmt.nim | 2 +- tests/macros/tdumpast2.nim | 2 +- tests/macros/texprcolonexpr.nim | 2 +- tests/macros/tgensym.nim | 2 +- tests/macros/tgentemplates.nim | 2 +- tests/macros/tgettype.nim | 8 +- tests/macros/tgettypeinst.nim | 2 +- tests/macros/tidgen.nim | 2 +- tests/macros/tmacro1.nim | 3 +- tests/macros/tmacro2.nim | 2 +- tests/macros/tmacro3.nim | 5 +- tests/macros/tmacro4.nim | 3 +- tests/macros/tmacro5.nim | 8 +- tests/macros/tmacro_in_template.nim | 4 +- tests/macros/tmacroaspragma.nim | 3 +- tests/macros/tmacros1.nim | 4 +- tests/macros/tmacrostmt.nim | 4 +- tests/macros/tmacrotypes.nim | 2 +- tests/macros/tnodecompare.nim | 6 +- tests/macros/tquotewords.nim | 5 +- tests/macros/trecmacro.nim | 2 +- tests/macros/treturnsempty.nim | 3 +- tests/macros/tsametype.nim | 2 +- tests/macros/tstaticparamsmacro.nim | 10 +- tests/macros/tstringinterp.nim | 7 +- tests/macros/ttryparseexpr.nim | 2 +- tests/macros/tvarnimnode.nim | 2 +- tests/macros/typesapi.nim | 2 +- tests/macros/typesapi2.nim | 5 +- tests/manyloc/keineschweine/keineschweine.nim | 5 +- tests/metatype/tbindtypedesc.nim | 4 +- tests/metatype/tmatrix.nim | 2 +- tests/metatype/tsemistatic.nim | 2 +- tests/metatype/tstatic_overloading.nim | 2 +- tests/metatype/tstaticparammacro.nim | 10 +- tests/metatype/tstaticparams.nim | 2 +- tests/metatype/ttypedesc1.nim | 2 +- tests/metatype/tymatrix.nim | 2 +- tests/misc/thallo.nim | 5 +- tests/misc/tints.nim | 2 +- tests/misc/tsimplesort.nim | 4 +- tests/objects/toop1.nim | 2 +- tests/overload/tparams_after_varargs.nim | 8 +- tests/overload/tspec.nim | 2 +- tests/overload/tstmtoverload.nim | 6 +- tests/parallel/tconvexhull.nim | 4 +- tests/parallel/tguard1.nim | 2 +- tests/parallel/tguard2.nim | 2 +- tests/parallel/tptr_to_ref.nim | 2 +- tests/parser/toprprec.nim | 11 +- tests/parser/tstrongspaces.nim | 10 +- tests/pragmas/tsym_as_pragma.nim | 2 +- tests/range/compilehelpers.nim | 5 +- tests/showoff/tdrdobbs_examples.nim | 6 +- tests/showoff/tformatopt.nim | 6 +- tests/showoff/thtml1.nim | 2 +- tests/showoff/thtml2.nim | 10 +- tests/showoff/tonce.nim | 2 +- tests/showoff/tquasiquote.nim | 2 +- tests/specialops/tdotops.nim | 3 +- tests/stdlib/tmarshal.nim | 2 +- tests/stdlib/tnre.nim | 17 +-- tests/stdlib/tpegs.nim | 22 ++-- tests/template/annotate.nim | 2 +- tests/template/mcan_access_hidden_field.nim | 3 +- tests/template/t2do.nim | 2 +- tests/template/t_otemplates.nim | 8 +- tests/template/tdefault_nil.nim | 2 +- tests/template/thygienictempl.nim | 4 +- tests/template/tissue909.nim | 2 +- tests/template/tissue993.nim | 7 +- tests/template/tit.nim | 2 +- tests/template/tparams_gensymed.nim | 2 +- tests/template/tprefer_immediate.nim | 6 +- tests/template/tscope.nim | 2 +- tests/template/tstmt_semchecked_twice.nim | 2 +- tests/template/tsymchoicefield.nim | 3 +- tests/template/ttempl3.nim | 12 +- tests/template/ttempl4.nim | 3 +- tests/template/ttempl5.nim | 5 +- tests/template/twhen_gensym.nim | 2 +- tests/template/twrongmapit.nim | 4 +- tests/template/twrongsymkind.nim | 2 +- tests/template/utemplates.nim | 15 +-- tests/trmacros/targlist.nim | 2 +- tests/trmacros/tcse.nim | 4 +- tests/trmacros/tmatrix.nim | 2 +- tests/trmacros/tnoalias.nim | 2 +- tests/trmacros/tnoalias2.nim | 2 +- tests/trmacros/tnoendlessrec.nim | 2 +- tests/trmacros/tor.nim | 8 +- tests/trmacros/tpartial.nim | 4 +- tests/trmacros/tstar.nim | 2 +- tests/trmacros/tstmtlist.nim | 2 +- tests/tuples/tuple_with_nil.nim | 2 +- tests/typerel/temptynode.nim | 2 +- tests/typerel/tsymchoice_for_expr.nim | 2 +- tests/typerel/tvarargsexpr.nim | 5 +- tests/types/tauto_canbe_void.nim | 2 +- tests/types/tisopr.nim | 4 +- tests/usingstmt/tusingstatement.nim | 4 +- tests/vm/tanonproc.nim | 2 +- tests/vm/tasmparser.nim | 70 +++++----- tests/vm/tcomponent.nim | 6 +- tests/vm/teval1.nim | 4 +- tests/vm/texcl.nim | 6 +- tests/vm/tmitems.nim | 4 +- tests/vm/tstaticprintseq.nim | 6 +- tests/vm/tstringnil.nim | 2 +- tests/vm/ttouintconv.nim | 14 +- tests/vm/twrongconst.nim | 2 +- 168 files changed, 499 insertions(+), 531 deletions(-) delete mode 100644 compiler/testability.nim (limited to 'lib/system.nim') diff --git a/compiler/evalffi.nim b/compiler/evalffi.nim index 987cfaf42..6789df87d 100644 --- a/compiler/evalffi.nim +++ b/compiler/evalffi.nim @@ -104,9 +104,9 @@ proc mapCallConv(cc: TCallingConvention, info: TLineInfo): TABI = else: globalError(info, "cannot map calling convention to FFI") -template rd(T, p: expr): expr {.immediate.} = (cast[ptr T](p))[] -template wr(T, p, v: expr) {.immediate.} = (cast[ptr T](p))[] = v -template `+!`(x, y: expr): expr {.immediate.} = +template rd(T, p: untyped): untyped = (cast[ptr T](p))[] +template wr(T, p, v: untyped): untyped = (cast[ptr T](p))[] = v +template `+!`(x, y: untyped): untyped = cast[pointer](cast[ByteAddress](x) + y) proc packSize(v: PNode, typ: PType): int = @@ -171,7 +171,7 @@ const maxPackDepth = 20 var packRecCheck = 0 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) case typ.kind @@ -302,7 +302,7 @@ proc canonNodeKind(k: TNodeKind): TNodeKind = else: result = k 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: result = newNode(k) result.typ = typ @@ -326,9 +326,9 @@ proc unpack(x: pointer, typ: PType, n: PNode): PNode = result.kind = nkNilLit result.typ = typ - template awi(kind, v: expr) {.immediate, dirty.} = aw(kind, v, intVal) - template awf(kind, v: expr) {.immediate, dirty.} = aw(kind, v, floatVal) - template aws(kind, v: expr) {.immediate, dirty.} = aw(kind, v, strVal) + template awi(kind, v: untyped): untyped = aw(kind, v, intVal) + template awf(kind, v: untyped): untyped = aw(kind, v, floatVal) + template aws(kind, v: untyped): untyped = aw(kind, v, strVal) case typ.kind of tyBool: awi(nkIntLit, rd(bool, x).ord) diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index 5ac2e678a..8ad8a6288 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -12,14 +12,14 @@ discard """ hygienic templates: - template `||` (a, b: expr): expr = + template `||` (a, b: untyped): untyped = let aa = a if aa: aa else: b var a, b: T - a || b || a + echo a || b || a Each evaluation context has to be different and we need to perform some form of preliminary symbol lookup in template definitions. Hygiene is diff --git a/compiler/testability.nim b/compiler/testability.nim deleted file mode 100644 index 4587a5344..000000000 --- a/compiler/testability.nim +++ /dev/null @@ -1,5 +0,0 @@ -template tests*(body: stmt) {.immediate.} = - when defined(selftest): - when not declared(unittest): import unittest - body - diff --git a/examples/allany.nim b/examples/allany.nim index 52a794204..6ff055aa6 100644 --- a/examples/allany.nim +++ b/examples/allany.nim @@ -1,6 +1,6 @@ # All and any -template all(container, cond: expr): expr {.immediate.} = +template all(container, cond: untyped): bool = block: var result = true for it in items(container): @@ -9,7 +9,7 @@ template all(container, cond: expr): expr {.immediate.} = break result -template any(container, cond: expr): expr {.immediate.} = +template any(container, cond: untyped): bool = block: var result = false for it in items(container): diff --git a/lib/core/typeinfo.nim b/lib/core/typeinfo.nim index c4b2ceca3..72b139202 100644 --- a/lib/core/typeinfo.nim +++ b/lib/core/typeinfo.nim @@ -97,7 +97,7 @@ proc newObj(typ: PNimType, size: int): pointer {.importCompilerProc.} proc newSeq(typ: PNimType, len: int): pointer {.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 = assert(n.kind == nkCase) diff --git a/lib/deprecated/pure/sockets.nim b/lib/deprecated/pure/sockets.nim index 415078126..1f96c8df1 100644 --- a/lib/deprecated/pure/sockets.nim +++ b/lib/deprecated/pure/sockets.nim @@ -206,16 +206,16 @@ proc htons*(x: int16): int16 = ## order, this is a no-op; otherwise, it performs a 2-byte swap operation. result = sockets.ntohs(x) -template ntohl(x: uint32): expr = +template ntohl(x: uint32): uint32 = cast[uint32](sockets.ntohl(cast[int32](x))) -template ntohs(x: uint16): expr = +template ntohs(x: uint16): uint16 = cast[uint16](sockets.ntohs(cast[int16](x))) -template htonl(x: uint32): expr = +template htonl(x: uint32): uint32 = sockets.ntohl(x) -template htons(x: uint16): expr = +template htons(x: uint16): uint16 = sockets.ntohs(x) when defined(Posix): @@ -442,14 +442,13 @@ proc parseIp4*(s: string): BiggestInt = if s[i] != '\0': invalidIp4(s) result = BiggestInt(a shl 24 or b shl 16 or c shl 8 or d) -template gaiNim(a, p, h, list: expr): stmt = - block: - var gaiResult = getaddrinfo(a, $p, addr(h), list) - if gaiResult != 0'i32: - when defined(windows): - raiseOSError(osLastError()) - else: - raiseOSError(osLastError(), $gai_strerror(gaiResult)) +template gaiNim(a, p, h, list: untyped): untyped = + var gaiResult = getaddrinfo(a, $p, addr(h), list) + if gaiResult != 0'i32: + when defined(windows): + raiseOSError(osLastError()) + else: + raiseOSError(osLastError(), $gai_strerror(gaiResult)) proc bindAddr*(socket: Socket, port = Port(0), address = "") {. tags: [ReadIOEffect].} = @@ -493,8 +492,8 @@ proc getSockName*(socket: Socket): Port = raiseOSError(osLastError()) result = Port(sockets.ntohs(name.sin_port)) -template acceptAddrPlain(noClientRet, successRet: expr, - sslImplementation: stmt): stmt {.immediate.} = +template acceptAddrPlain(noClientRet, successRet: int, + sslImplementation: untyped): untyped = assert(client != nil) var sockAddress: Sockaddr_in var addrLen = sizeof(sockAddress).SockLen @@ -594,7 +593,7 @@ when defined(ssl): ## ## ``AcceptNoClient`` will be returned when no client is currently attempting ## to connect. - template doHandshake(): stmt = + template doHandshake(): untyped = when defined(ssl): if server.isSSL: 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 ## favour of readLine. - template addNLIfEmpty(): stmt = + template addNLIfEmpty(): untyped = if line.len == 0: 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 ## the specified time an ETimeout exception will be raised. - template addNLIfEmpty(): stmt = + template addNLIfEmpty(): untyped = if line.len == 0: line.add("\c\L") diff --git a/lib/impure/nre/private/util.nim b/lib/impure/nre/private/util.nim index 253bfada7..12d2506ea 100644 --- a/lib/impure/nre/private/util.nim +++ b/lib/impure/nre/private/util.nim @@ -16,7 +16,7 @@ proc checkNil(arg: string): string = else: return arg -template formatStr*(howExpr, namegetter, idgetter: expr): expr = +template formatStr*(howExpr, namegetter, idgetter): untyped = let how = howExpr var val = newStringOfCap(how.len) var i = 0 diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim index ce63d780c..13016bfc0 100644 --- a/lib/packages/docutils/rstgen.nim +++ b/lib/packages/docutils/rstgen.nim @@ -765,7 +765,7 @@ proc renderTocEntries*(d: var RstGenerator, j: var int, lvl: int, result.add(tmp) 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'} + Digits + Letters + WhiteSpace) let @@ -1194,7 +1194,7 @@ proc defaultConfig*(): StringTableRef = ## ``rstToHtml`` to generate the bare minimum HTML. result = newStringTable(modeStyleInsensitive) - template setConfigVar(key, val: expr) = + template setConfigVar(key, val) = result[key] = val # If you need to modify these values, it might be worth updating the template diff --git a/lib/posix/termios.nim b/lib/posix/termios.nim index 21b21aefb..f86e408fb 100644 --- a/lib/posix/termios.nim +++ b/lib/posix/termios.nim @@ -174,7 +174,7 @@ var # 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. -template cceq*(val, c: expr): expr = +template cceq*(val, c): untyped = c == val and val != POSIX_VDISABLE # Return the output baud rate stored in *TERMIOS_P. diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 28b20feaa..281d5b848 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -1317,7 +1317,7 @@ proc recvLine*(socket: AsyncFD): Future[string] {.async, deprecated.} = ## ## **Deprecated since version 0.15.0**: Use ``asyncnet.recvLine()`` instead. - template addNLIfEmpty(): stmt = + template addNLIfEmpty(): untyped = if result.len == 0: result.add("\c\L") diff --git a/lib/pure/asyncnet.nim b/lib/pure/asyncnet.nim index 5de65efe0..5be457d2a 100644 --- a/lib/pure/asyncnet.nim +++ b/lib/pure/asyncnet.nim @@ -220,7 +220,7 @@ when defineSsl: raiseSSLError("Cannot appease SSL.") template sslLoop(socket: AsyncSocket, flags: set[SocketFlag], - op: expr) = + op: untyped) = var opResult {.inject.} = -1.cint while opResult < 0: # Call the desired operation. @@ -490,7 +490,7 @@ proc recvLineInto*(socket: AsyncSocket, resString: FutureVar[string], # them when the result future is completed. # Can we replace the result future with the FutureVar? - template addNLIfEmpty(): stmt = + template addNLIfEmpty(): untyped = if resString.mget.len == 0: resString.mget.add("\c\L") diff --git a/lib/pure/basic2d.nim b/lib/pure/basic2d.nim index e4696c6a8..31b3814d6 100644 --- a/lib/pure/basic2d.nim +++ b/lib/pure/basic2d.nim @@ -116,13 +116,13 @@ proc safeArccos(v:float):float= return arccos(clamp(v,-1.0,1.0)) -template makeBinOpVector(s:expr)= +template makeBinOpVector(s) = ## 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: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)) -template makeBinOpAssignVector(s:expr)= +template makeBinOpAssignVector(s)= ## 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: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.}= ## converts `rad` radians to degrees rad * RAD2DEGCONST - - diff --git a/lib/pure/basic3d.nim b/lib/pure/basic3d.nim index f7a9c237c..e2d2464c0 100644 --- a/lib/pure/basic3d.nim +++ b/lib/pure/basic3d.nim @@ -116,7 +116,7 @@ proc safeArccos(v:float):float= ## due to rounding issues return arccos(clamp(v,-1.0,1.0)) -template makeBinOpVector(s:expr)= +template makeBinOpVector(s) = proc s*(a,b:Vector3d):Vector3d {.inline,noInit.} = 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.} = @@ -124,7 +124,7 @@ template makeBinOpVector(s:expr)= proc s*(a:float,b:Vector3d):Vector3d {.inline,noInit.} = 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.} = s(a.x,b.x); s(a.y,b.y); s(a.z,b.z) proc s*(a:var Vector3d,b:float) {.inline.} = diff --git a/lib/pure/collections/critbits.nim b/lib/pure/collections/critbits.nim index 519c58653..5f84f3101 100644 --- a/lib/pure/collections/critbits.nim +++ b/lib/pure/collections/critbits.nim @@ -143,15 +143,16 @@ proc `[]=`*[T](c: var CritBitTree[T], key: string, val: T) = var n = rawInsert(c, key) 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) - if n != nil: result = n.val - else: + if n == nil: when compiles($key): raise newException(KeyError, "key not found: " & $key) else: raise newException(KeyError, "key not found") + n.val + proc `[]`*[T](c: CritBitTree[T], key: string): T {.inline, deprecatedGet.} = ## retrieves the value at ``c[key]``. If `key` is not in `t`, the ## ``KeyError`` exception is raised. One can check with ``hasKey`` whether diff --git a/lib/pure/collections/intsets.nim b/lib/pure/collections/intsets.nim index 4ecac11be..cf7aab18e 100644 --- a/lib/pure/collections/intsets.nim +++ b/lib/pure/collections/intsets.nim @@ -189,7 +189,7 @@ iterator items*(s: IntSet): int {.inline.} = inc(i) r = r.next -template dollarImpl(): stmt = +template dollarImpl(): untyped = result = "{" for key in items(s): if result.len > 1: result.add(", ") diff --git a/lib/pure/collections/sequtils.nim b/lib/pure/collections/sequtils.nim index 19512d5f4..e8e725aa3 100644 --- a/lib/pure/collections/sequtils.nim +++ b/lib/pure/collections/sequtils.nim @@ -455,7 +455,7 @@ template anyIt*(seq1, pred: untyped): bool = break result -template toSeq*(iter: untyped): untyped {.oldimmediate.} = +template toSeq*(iter: untyped): untyped = ## Transforms any iterator into a sequence. ## ## Example: diff --git a/lib/pure/collections/sharedtables.nim b/lib/pure/collections/sharedtables.nim index de573bcb2..fc50ea41c 100644 --- a/lib/pure/collections/sharedtables.nim +++ b/lib/pure/collections/sharedtables.nim @@ -25,7 +25,7 @@ type counter, dataLen: int lock: Lock -template maxHash(t): expr = t.dataLen-1 +template maxHash(t): untyped = t.dataLen-1 include tableimpl diff --git a/lib/pure/collections/tableimpl.nim b/lib/pure/collections/tableimpl.nim index c0d45c392..eec98fcaf 100644 --- a/lib/pure/collections/tableimpl.nim +++ b/lib/pure/collections/tableimpl.nim @@ -85,7 +85,7 @@ template addImpl(enlarge) {.dirty.} = rawInsert(t, t.data, key, val, hc, j) inc(t.counter) -template maybeRehashPutImpl(enlarge) {.oldimmediate, dirty.} = +template maybeRehashPutImpl(enlarge) {.dirty.} = if mustRehash(t.dataLen, t.counter): enlarge(t) index = rawGetKnownHC(t, key, hc) @@ -93,7 +93,7 @@ template maybeRehashPutImpl(enlarge) {.oldimmediate, dirty.} = rawInsert(t, t.data, key, val, hc, index) inc(t.counter) -template putImpl(enlarge) {.oldimmediate, dirty.} = +template putImpl(enlarge) {.dirty.} = var hc: Hash var index = rawGet(t, key, hc) if index >= 0: t.data[index].val = val diff --git a/lib/pure/colors.nim b/lib/pure/colors.nim index f4c027576..4ec76dee0 100644 --- a/lib/pure/colors.nim +++ b/lib/pure/colors.nim @@ -19,18 +19,18 @@ type proc `==` *(a, b: Color): bool {.borrow.} ## 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 g = a.int shr 8 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) -template colorOp(op: expr) {.immediate.} = +template colorOp(op): Color = extract(a, ar, ag, ab) 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.} = result = a +% b @@ -67,12 +67,12 @@ proc intensity*(a: Color, f: float): Color = if b >% 255: b = 255 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 ## 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 ## 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 block: var y = x # eval only once diff --git a/lib/pure/concurrency/threadpool.nim b/lib/pure/concurrency/threadpool.nim index cf4f58588..2a0dbd2ca 100644 --- a/lib/pure/concurrency/threadpool.nim +++ b/lib/pure/concurrency/threadpool.nim @@ -409,20 +409,20 @@ proc preferSpawn*(): bool = ## it is not necessary to call this directly; use 'spawnX' instead. 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 ## 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 ## 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 ## the 'call' is **always** executed on ## the thread. 'call' has to be proc call 'p(...)' where 'p' ## is gcsafe and has a return type that is either 'void' or compatible ## 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 ## call in the calling thread. Usually it is advised to ## use 'spawn' in order to not block the producer for an unknown @@ -431,7 +431,7 @@ template spawnX*(call: expr): expr = ## with ``FlowVar[T]``. (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`` ## has to be in a DSL that is a particular subset of the language. Please ## refer to the manual for further information. diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim index b6154d8de..d1cf5d9bc 100644 --- a/lib/pure/memfiles.nim +++ b/lib/pure/memfiles.nim @@ -123,7 +123,7 @@ proc open*(filename: string, mode: FileMode = fmRead, result.size = 0 when defined(windows): - template fail(errCode: OSErrorCode, msg: expr) = + template fail(errCode: OSErrorCode, msg: untyped) = rollback() if result.fHandle != 0: discard closeHandle(result.fHandle) if result.mapHandle != 0: discard closeHandle(result.mapHandle) @@ -131,7 +131,7 @@ proc open*(filename: string, mode: FileMode = fmRead, # return false #raise newException(EIO, msg) - template callCreateFile(winApiProc, filename: expr): expr = + template callCreateFile(winApiProc, filename): untyped = winApiProc( filename, # GENERIC_ALL != (GENERIC_READ or GENERIC_WRITE) @@ -198,7 +198,7 @@ proc open*(filename: string, mode: FileMode = fmRead, result.fHandle = INVALID_HANDLE_VALUE else: - template fail(errCode: OSErrorCode, msg: expr) = + template fail(errCode: OSErrorCode, msg: string) = rollback() if result.handle != -1: discard close(result.handle) raiseOSError(errCode) diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 629e916fa..215a301b6 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -797,7 +797,7 @@ when false: #defineSsl: ## ## ``AcceptNoClient`` will be returned when no client is currently attempting ## to connect. - template doHandshake(): stmt = + template doHandshake(): untyped = when defineSsl: if server.isSSL: client.setBlocking(false) diff --git a/lib/pure/pegs.nim b/lib/pure/pegs.nim index 6a52e2cd5..5ae2d9182 100644 --- a/lib/pure/pegs.nim +++ b/lib/pure/pegs.nim @@ -139,7 +139,7 @@ proc addChoice(dest: var Peg, elem: Peg) = else: add(dest, elem) else: add(dest, elem) -template multipleOp(k: PegKind, localOpt: expr) = +template multipleOp(k: PegKind, localOpt: untyped) = result.kind = k result.sons = @[] for x in items(a): @@ -328,32 +328,32 @@ proc newNonTerminal*(name: string, line, column: int): NonTerminal {. result.line = line result.col = column -template letters*: expr = +template letters*: Peg = ## expands to ``charset({'A'..'Z', 'a'..'z'})`` charSet({'A'..'Z', 'a'..'z'}) -template digits*: expr = +template digits*: Peg = ## expands to ``charset({'0'..'9'})`` charSet({'0'..'9'}) -template whitespace*: expr = +template whitespace*: Peg = ## expands to ``charset({' ', '\9'..'\13'})`` charSet({' ', '\9'..'\13'}) -template identChars*: expr = +template identChars*: Peg = ## expands to ``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', '_'})`` charSet({'a'..'z', 'A'..'Z', '_'}) -template ident*: expr = +template ident*: Peg = ## same as ``[a-zA-Z_][a-zA-z_0-9]*``; standard identifier sequence(charSet({'a'..'z', 'A'..'Z', '_'}), *charSet({'a'..'z', 'A'..'Z', '0'..'9', '_'})) -template natural*: expr = +template natural*: Peg = ## same as ``\d+`` +digits @@ -514,10 +514,10 @@ proc bounds*(c: Captures, when not useUnicode: type Rune = char - template fastRuneAt(s, i, ch: expr) = + template fastRuneAt(s, i, ch) = ch = s[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 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 of pkRule, pkList: assert false -template fillMatches(s, caps, c: expr) = +template fillMatches(s, caps, c) = for k in 0..c.ml-1: let startIdx = c.matches[k][0] let endIdx = c.matches[k][1] diff --git a/lib/pure/subexes.nim b/lib/pure/subexes.nim index 351b3c086..9d807abd4 100644 --- a/lib/pure/subexes.nim +++ b/lib/pure/subexes.nim @@ -46,12 +46,12 @@ type num, i, lineLen: int {.deprecated: [TFormatParser: FormatParser].} -template call(x: stmt) {.immediate.} = +template call(x: untyped): untyped = p.i = i x i = p.i -template callNoLineLenTracking(x: stmt) {.immediate.} = +template callNoLineLenTracking(x: untyped): untyped = let oldLineLen = p.lineLen p.i = i x diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim index 87c663c3d..871ac5d39 100644 --- a/lib/pure/terminal.nim +++ b/lib/pure/terminal.nim @@ -578,7 +578,7 @@ template styledEchoProcessArg(f: File, cmd: TerminalCmd) = when cmd == resetStyle: 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. ## When some argument is ``Style``, ``set[Style]``, ``ForegroundColor``, ## ``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"))) 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.add(bindSym"stdout") - for arg in children(args[0][1]): + for arg in children(args): result.add(arg) -template styledEcho*(args: varargs[expr]): expr = - ## Echoes styles arguments to stdout using ``styledWriteLine``. - callStyledEcho(args) - proc getch*(): char = ## Read a single character from the terminal, blocking until it is entered. ## The character is not printed to the terminal. diff --git a/lib/pure/uri.nim b/lib/pure/uri.nim index c7e0ed1da..dd6e6c9af 100644 --- a/lib/pure/uri.nim +++ b/lib/pure/uri.nim @@ -215,7 +215,7 @@ proc combine*(base: Uri, reference: Uri): Uri = ## let bar = combine(parseUri("http://example.com/foo/bar/"), parseUri("baz")) ## assert bar.path == "/foo/bar/baz" - template setAuthority(dest, src: expr): stmt = + template setAuthority(dest, src): untyped = dest.hostname = src.hostname dest.username = src.username dest.port = src.port diff --git a/lib/pure/xmltree.nim b/lib/pure/xmltree.nim index 7cfb62157..45696c80c 100644 --- a/lib/pure/xmltree.nim +++ b/lib/pure/xmltree.nim @@ -338,7 +338,7 @@ proc xmlConstructor(e: NimNode): NimNode {.compileTime.} = else: result = newCall("newXmlTree", toStrLit(a)) -macro `<>`*(x: expr): expr {.immediate.} = +macro `<>`*(x: untyped): untyped = ## Constructor macro for XML. Example usage: ## ## .. code-block:: nim diff --git a/lib/system.nim b/lib/system.nim index d62c0424e..f84a47df0 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -80,9 +80,10 @@ type `nil` {.magic: "Nil".} 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) - ## **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 auto* {.magic: Expr.} ## meta type for automatic type determination 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 dec(res, step) -template countupImpl(incr: untyped) {.oldimmediate, dirty.} = +iterator countup*[S, T](a: S, b: T, step = 1): T {.inline.} = + ## Counts from ordinal value `a` up to `b` (inclusive) with the given + ## 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 + ## efficiency reasons. when T is IntLikeForCount: var res = int(a) while res <= int(b): yield T(res) - incr + inc(res, step) else: var res: T = T(a) while res <= b: yield res - incr - -iterator countup*[S, T](a: S, b: T, step = 1): T {.inline.} = - ## Counts from ordinal value `a` up to `b` (inclusive) with the given - ## 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 - ## efficiency reasons. - countupImpl: - inc(res, step) + inc(res, step) iterator `..`*[S, T](a: S, b: T): T {.inline.} = ## An alias for `countup`. - countupImpl: - inc(res) + when T is IntLikeForCount: + 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 {. inline, magic: "OmpParFor", sideEffect.} = diff --git a/lib/system/channels.nim b/lib/system/channels.nim index 572f12e84..e3baff797 100644 --- a/lib/system/channels.nim +++ b/lib/system/channels.nim @@ -203,12 +203,12 @@ proc rawRecv(q: PRawChannel, data: pointer, typ: PNimType) = storeAux(data, addr(q.data[q.rd * typ.size]), typ, q, mLoad) q.rd = (q.rd + 1) and q.mask -template lockChannel(q: expr, action: stmt) {.immediate.} = +template lockChannel(q, action): untyped = acquireSys(q.lock) action releaseSys(q.lock) -template sendImpl(q: expr) {.immediate.} = +template sendImpl(q) = if q.mask == ChannelDeadMask: sysFatal(DeadThreadError, "cannot send message; thread died") acquireSys(q.lock) diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim index e35b0bd5d..cee4e33a5 100644 --- a/lib/system/excpt.nim +++ b/lib/system/excpt.nim @@ -276,11 +276,11 @@ proc raiseExceptionAux(e: ref Exception) = quitOrDebug() else: # ugly, but avoids heap allocations :-) - template xadd(buf, s, slen: expr) = + template xadd(buf, s, slen) = if L + slen < high(buf): copyMem(addr(buf[L]), cstring(s), slen) inc L, slen - template add(buf, s: expr) = + template add(buf, s) = xadd(buf, s, s.len) var buf: array[0..2000, char] var L = 0 @@ -387,7 +387,8 @@ when not defined(noSignalHandler): GC_enable() else: var msg: cstring - template asgn(y: expr) = msg = y + template asgn(y) = + msg = y processSignal(sign, asgn) showErrorMessage(msg) when defined(endb): dbgAborting = true diff --git a/lib/system/threads.nim b/lib/system/threads.nim index bb03b6d0e..8041b8a8f 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -447,7 +447,7 @@ proc threadProcWrapStackFrame[TArg](thrd: ptr Thread[TArg]) = else: threadProcWrapDispatch(thrd) -template threadProcWrapperBody(closure: expr) {.immediate.} = +template threadProcWrapperBody(closure: untyped): untyped = var thrd = cast[ptr Thread[TArg]](closure) var core = thrd.core when declared(globalsSlot): threadVarSetValue(globalsSlot, thrd.core) diff --git a/tests/alias/talias.nim b/tests/alias/talias.nim index 810ea2095..a8f1b0dd0 100644 --- a/tests/alias/talias.nim +++ b/tests/alias/talias.nim @@ -8,17 +8,17 @@ proc isPartOf*[S, T](a: S, b: T): TAnalysisResult {. magic: "IsPartOf", noSideEffect.} ## not yet exported properly. -template compileTimeAssert(cond: expr) = +template compileTimeAssert(cond) = when not cond: {.compile: "is false: " & astToStr(cond).} -template `<|` (a, b: expr) = +template `<|` (a, b) = compileTimeAssert isPartOf(a, b) == arYes -template `!<|` (a, b: expr) = +template `!<|` (a, b) = compileTimeAssert isPartOf(a, b) == arNo -template `?<|` (a, b: expr) = +template `?<|` (a, b) = compileTimeAssert isPartOf(a, b) == arMaybe type diff --git a/tests/assert/tuserassert.nim b/tests/assert/tuserassert.nim index 7bb0a7fc0..274c78921 100644 --- a/tests/assert/tuserassert.nim +++ b/tests/assert/tuserassert.nim @@ -2,7 +2,7 @@ discard """ output: "x == 45ugh" """ -template myAssert(cond: expr) = +template myAssert(cond: untyped) = when 3 <= 3: let c = cond.astToStr if not cond: diff --git a/tests/bind/mbind3.nim b/tests/bind/mbind3.nim index aad080223..1a7d3b63b 100644 --- a/tests/bind/mbind3.nim +++ b/tests/bind/mbind3.nim @@ -2,7 +2,7 @@ var lastId = 0 -template genId*: expr = +template genId*: int = bind lastId inc(lastId) lastId diff --git a/tests/bind/tbind1.nim b/tests/bind/tbind1.nim index 2665d0b5c..9b13a7d11 100644 --- a/tests/bind/tbind1.nim +++ b/tests/bind/tbind1.nim @@ -6,7 +6,7 @@ discard """ proc p1(x: int8, y: int): int = return x + y -template tempBind(x, y: expr): expr = +template tempBind(x, y): untyped = bind p1 p1(x, y) diff --git a/tests/bind/tbind2.nim b/tests/bind/tbind2.nim index 0e0cbd788..799b14381 100644 --- a/tests/bind/tbind2.nim +++ b/tests/bind/tbind2.nim @@ -8,7 +8,7 @@ discard """ proc p1(x: int8, y: int): 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 echo tempBind(1'i8, 2'i8) diff --git a/tests/ccgbugs/tnocodegen_for_compiletime.nim b/tests/ccgbugs/tnocodegen_for_compiletime.nim index a88ba4b32..b44e9f8c9 100644 --- a/tests/ccgbugs/tnocodegen_for_compiletime.nim +++ b/tests/ccgbugs/tnocodegen_for_compiletime.nim @@ -1,7 +1,7 @@ # bug #1679 import macros, tables, hashes 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]() a.inc(body) diff --git a/tests/ccgbugs/tuple_canon.nim b/tests/ccgbugs/tuple_canon.nim index a607f9cab..45fed8eee 100644 --- a/tests/ccgbugs/tuple_canon.nim +++ b/tests/ccgbugs/tuple_canon.nim @@ -59,7 +59,7 @@ let ((1,1), hiA), ((0,1), hiB)] -template odd*(i: int) : expr = +template odd*(i: int) : untyped = (i and 1) != 0 proc vidx(hg: HexGrid; col, row: int; i: HexVtxIndex) : Index = diff --git a/tests/closure/tmacrobust1512.nim b/tests/closure/tmacrobust1512.nim index 95681e750..5f13e8286 100644 --- a/tests/closure/tmacrobust1512.nim +++ b/tests/closure/tmacrobust1512.nim @@ -2,109 +2,109 @@ import macros, strutils # https://github.com/nim-lang/Nim/issues/1512 -proc macrobust0 (raw_input: string) = +proc macrobust0(raw_input: string) = var output = "" - proc p1 (a:string) = - output.add (a) - - proc p2 (a:string) = p1 (a) - proc p3 (a:string) = p2 (a) - proc p4 (a:string) = p3 (a) - proc p5 (a:string) = p4 (a) - proc p6 (a:string) = p5 (a) - proc p7 (a:string) = p6 (a) - proc p8 (a:string) = p7 (a) - proc p9 (a:string) = p8 (a) - proc p10 (a:string) = p9 (a) - proc p11 (a:string) = p10 (a) - proc p12 (a:string) = p11 (a) - proc p13 (a:string) = p12 (a) - proc p14 (a:string) = p13 (a) - proc p15 (a:string) = p14 (a) - proc p16 (a:string) = p15 (a) - proc p17 (a:string) = p16 (a) - proc p18 (a:string) = p17 (a) - proc p19 (a:string) = p18 (a) - proc p20 (a:string) = p19 (a) + proc p1(a:string) = + output.add(a) + + proc p2(a:string) = p1(a) + proc p3(a:string) = p2(a) + proc p4(a:string) = p3(a) + proc p5(a:string) = p4(a) + proc p6(a:string) = p5(a) + proc p7(a:string) = p6(a) + proc p8(a:string) = p7(a) + proc p9(a:string) = p8(a) + proc p10(a:string) = p9(a) + proc p11(a:string) = p10(a) + proc p12(a:string) = p11(a) + proc p13(a:string) = p12(a) + proc p14(a:string) = p13(a) + proc p15(a:string) = p14(a) + proc p16(a:string) = p15(a) + proc p17(a:string) = p16(a) + proc p18(a:string) = p17(a) + proc p19(a:string) = p18(a) + proc p20(a:string) = p19(a) let input = $raw_input - for a in input.split (): - p20 (a) - p19 (a) - - - p18 (a) - p17 (a) - p16 (a) - p15 (a) - p14 (a) - p13 (a) - p12 (a) - p11 (a) - p10 (a) - p9 (a) - p8 (a) - p7 (a) - p6 (a) - p5 (a) - p4 (a) - p3 (a) - p2 (a) - p1 (a) + for a in input.split(): + p20(a) + p19(a) + + + p18(a) + p17(a) + p16(a) + p15(a) + p14(a) + p13(a) + p12(a) + p11(a) + p10(a) + p9(a) + p8(a) + p7(a) + p6(a) + p5(a) + p4(a) + p3(a) + p2(a) + p1(a) echo output -macro macrobust (raw_input: expr) : stmt = +macro macrobust(raw_input: untyped): untyped = var output = "" - proc p1 (a:string) = - output.add (a) - - proc p2 (a:string) = p1 (a) - proc p3 (a:string) = p2 (a) - proc p4 (a:string) = p3 (a) - proc p5 (a:string) = p4 (a) - proc p6 (a:string) = p5 (a) - proc p7 (a:string) = p6 (a) - proc p8 (a:string) = p7 (a) - proc p9 (a:string) = p8 (a) - proc p10 (a:string) = p9 (a) - proc p11 (a:string) = p10 (a) - proc p12 (a:string) = p11 (a) - proc p13 (a:string) = p12 (a) - proc p14 (a:string) = p13 (a) - proc p15 (a:string) = p14 (a) - proc p16 (a:string) = p15 (a) - proc p17 (a:string) = p16 (a) - proc p18 (a:string) = p17 (a) - proc p19 (a:string) = p18 (a) - proc p20 (a:string) = p19 (a) + proc p1(a:string) = + output.add(a) + + proc p2(a:string) = p1(a) + proc p3(a:string) = p2(a) + proc p4(a:string) = p3(a) + proc p5(a:string) = p4(a) + proc p6(a:string) = p5(a) + proc p7(a:string) = p6(a) + proc p8(a:string) = p7(a) + proc p9(a:string) = p8(a) + proc p10(a:string) = p9(a) + proc p11(a:string) = p10(a) + proc p12(a:string) = p11(a) + proc p13(a:string) = p12(a) + proc p14(a:string) = p13(a) + proc p15(a:string) = p14(a) + proc p16(a:string) = p15(a) + proc p17(a:string) = p16(a) + proc p18(a:string) = p17(a) + proc p19(a:string) = p18(a) + proc p20(a:string) = p19(a) let input = $raw_input - for a in input.split (): - p20 (a) - p19 (a) - - p18 (a) - p17 (a) - p16 (a) - p15 (a) - p14 (a) - p13 (a) - p12 (a) - p11 (a) - p10 (a) - p9 (a) - p8 (a) - p7 (a) - p6 (a) - p5 (a) - p4 (a) - p3 (a) - p2 (a) + for a in input.split(): + p20(a) + p19(a) + + p18(a) + p17(a) + p16(a) + p15(a) + p14(a) + p13(a) + p12(a) + p11(a) + p10(a) + p9(a) + p8(a) + p7(a) + p6(a) + p5(a) + p4(a) + p3(a) + p2(a) echo output discard result @@ -134,4 +134,4 @@ macrobust0 """ sdafsdaffsda sdfasadfsadf fsdasdafsdfa sdfasdfafsda sdfasdafsadf sdfasdafsdaf sdfasdafsdaf -""" \ No newline at end of file +""" diff --git a/tests/collections/ttableconstr.nim b/tests/collections/ttableconstr.nim index a9262e70e..884378a76 100644 --- a/tests/collections/ttableconstr.nim +++ b/tests/collections/ttableconstr.nim @@ -1,6 +1,6 @@ # Test if the new table constructor syntax works: -template ignoreExpr(e: expr): stmt {.immediate.} = +template ignoreExpr(e) = discard # test first class '..' syntactical citizen: diff --git a/tests/compiles/tcompiles.nim b/tests/compiles/tcompiles.nim index b3d9c17ce..1a21315c8 100644 --- a/tests/compiles/tcompiles.nim +++ b/tests/compiles/tcompiles.nim @@ -1,13 +1,15 @@ # 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)) -template ok(x: expr): stmt = - static: assert(x) +template ok(x) = + static: + assert(x) -template no(x: expr): stmt = - static: assert(not x) +template no(x) = + static: + assert(not x) type TObj = object diff --git a/tests/concepts/matrix.nim b/tests/concepts/matrix.nim index a30cbe4f3..47a709f80 100644 --- a/tests/concepts/matrix.nim +++ b/tests/concepts/matrix.nim @@ -9,7 +9,6 @@ proc `[]=`*(M: var Matrix; m, n: int; v: M.T) = M.data[m * M.N + n] = v # Adapt the Matrix type to the concept's requirements -template Rows*(M: type Matrix): expr = M.M -template Cols*(M: type Matrix): expr = M.N +template Rows*(M: type Matrix): untyped = M.M +template Cols*(M: type Matrix): untyped = M.N template ValueType*(M: type Matrix): typedesc = M.T - diff --git a/tests/concepts/tmanual.nim b/tests/concepts/tmanual.nim index 43290a6ad..c917f5022 100644 --- a/tests/concepts/tmanual.nim +++ b/tests/concepts/tmanual.nim @@ -14,10 +14,10 @@ t ''' """ -template accept(e: expr) = +template accept(e) = static: assert compiles(e) -template reject(e: expr) = +template reject(e) = static: assert(not compiles(e)) type @@ -40,4 +40,3 @@ takesContainer(@[4, 5, 6]) takesContainer(@["a", "b"]) takesContainer "test" reject takesContainer(10) - diff --git a/tests/concepts/tstackconcept.nim b/tests/concepts/tstackconcept.nim index b6ead2c2b..2238dacb6 100644 --- a/tests/concepts/tstackconcept.nim +++ b/tests/concepts/tstackconcept.nim @@ -12,7 +12,7 @@ IMPLICIT VALUE TYPE NAME INT INT import typetraits, strutils -template reject(e: expr) = +template reject(e) = static: assert(not compiles(e)) type @@ -60,4 +60,3 @@ reject s.genericAlgorithm "x" reject s.genericAlgorithm 1.0 reject "str".implicitGeneric reject implicitGeneric(10) - diff --git a/tests/discard/tdiscardable.nim b/tests/discard/tdiscardable.nim index 99adcfd30..662d2725a 100644 --- a/tests/discard/tdiscardable.nim +++ b/tests/discard/tdiscardable.nim @@ -13,7 +13,7 @@ q[float](0.8, 0.2) # bug #942 -template maybeMod(x: Tinteger, module:Natural):expr = +template maybeMod(x: Tinteger, module:Natural): untyped = if module > 0: x mod module else: x diff --git a/tests/exception/tdefer1.nim b/tests/exception/tdefer1.nim index cb3d09b01..b84ba7681 100644 --- a/tests/exception/tdefer1.nim +++ b/tests/exception/tdefer1.nim @@ -10,7 +10,7 @@ A''' # bug #1742 -template test(): expr = +template test(): untyped = let a = 0 defer: echo "hi" a @@ -29,7 +29,7 @@ template atFuncEnd = defer: echo "B" -template testB(): expr = +template testB(): untyped = let a = 0 defer: echo "hi" # Delete this line to make it work a diff --git a/tests/fields/tfields_in_template.nim b/tests/fields/tfields_in_template.nim index 9352a7a51..b7d5d2343 100644 --- a/tests/fields/tfields_in_template.nim +++ b/tests/fields/tfields_in_template.nim @@ -9,7 +9,7 @@ for name, value in (n: "v").fieldPairs: echo name # 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: echo name wrapper() diff --git a/tests/float/tfloat7.nim b/tests/float/tfloat7.nim index 2337d1dd4..5fd0d43d9 100644 --- a/tests/float/tfloat7.nim +++ b/tests/float/tfloat7.nim @@ -10,7 +10,7 @@ passed.''' """ import strutils -template expect_fail(x: expr) = +template expect_fail(x) = try: discard x echo("expected to fail!") diff --git a/tests/generics/tgeneric3.nim b/tests/generics/tgeneric3.nim index 0dbd5b03c..d014eb998 100644 --- a/tests/generics/tgeneric3.nim +++ b/tests/generics/tgeneric3.nim @@ -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.} = return a-b -template binSearchImpl *(docmp: expr) {.immediate.} = +template binSearchImpl *(docmp: untyped) = var bFound = false result = 0 var H = haystack.len - 1 diff --git a/tests/generics/tgenerictmpl.nim b/tests/generics/tgenerictmpl.nim index c71ce4e2e..e18f020c2 100644 --- a/tests/generics/tgenerictmpl.nim +++ b/tests/generics/tgenerictmpl.nim @@ -5,7 +5,7 @@ discard """ # 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 diff --git a/tests/generics/tgenerictmpl2.nim b/tests/generics/tgenerictmpl2.nim index 0ecaf9ded..ac92d3281 100644 --- a/tests/generics/tgenerictmpl2.nim +++ b/tests/generics/tgenerictmpl2.nim @@ -27,5 +27,5 @@ ttmpl[int] #<- crash case #3 # 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] diff --git a/tests/generics/tunique_type.nim b/tests/generics/tunique_type.nim index da2f9e4b2..ccb367ac8 100644 --- a/tests/generics/tunique_type.nim +++ b/tests/generics/tunique_type.nim @@ -36,7 +36,7 @@ proc derefExpr(exprRef: string): NimNode {.compileTime.} = type Mapped[Input; predicate: static[string]] = object input: Input -macro map(input, predicate: expr): expr = +macro map(input, predicate: untyped): untyped = let predicate = callsite()[2] newNimNode(nnkObjConstr).add( newNimNode(nnkBracketExpr).add( @@ -47,7 +47,7 @@ macro map(input, predicate: expr): expr = ident"input", input)) proc `[]`(m: Mapped, i: int): auto = - macro buildResult: expr = + macro buildResult: untyped = newCall( derefExpr(m.predicate), newNimNode(nnkBracketExpr).add( diff --git a/tests/gensym/tgensym.nim b/tests/gensym/tgensym.nim index 3c85b0b83..e33a2783f 100644 --- a/tests/gensym/tgensym.nim +++ b/tests/gensym/tgensym.nim @@ -2,7 +2,7 @@ discard """ output: "123100" """ -template hygienic(val: expr) = +template hygienic(val) = var x = val stdout.write x diff --git a/tests/lexer/tind1.nim b/tests/lexer/tind1.nim index 6a975d5be..8a2aea9b2 100644 --- a/tests/lexer/tind1.nim +++ b/tests/lexer/tind1.nim @@ -11,17 +11,15 @@ var x = if 4 != 5: else: "no" -macro mymacro(n: expr): stmt {.immediate.} = nil +macro mymacro(n): untyped {.immediate.} = + discard mymacro: echo "test" else: echo "else part" - if 4 == 3: echo "bug" else: echo "no bug" - - diff --git a/tests/macros/tbindsym.nim b/tests/macros/tbindsym.nim index e1e3b5112..6289d3eb2 100644 --- a/tests/macros/tbindsym.nim +++ b/tests/macros/tbindsym.nim @@ -11,7 +11,7 @@ type TTextKind = enum TFoo, TBar -macro test: stmt = +macro test: untyped = var x = @[TFoo, TBar] result = newStmtList() for i in x: diff --git a/tests/macros/tbugs.nim b/tests/macros/tbugs.nim index 1bfce6bc4..990edf1e2 100644 --- a/tests/macros/tbugs.nim +++ b/tests/macros/tbugs.nim @@ -26,7 +26,7 @@ iterator test2(f: string): Foo = for i in f: yield Foo(s: i) -macro test(): stmt = +macro test(): untyped = for i in test2("asdf"): echo i.s @@ -39,7 +39,7 @@ import macros type TType = tuple[s: string] -macro echotest(): stmt = +macro echotest(): untyped = var t: TType t.s = "" t.s.add("test") @@ -61,7 +61,7 @@ proc get_data(d: Td) : string {.compileTime.} = #result.add("aa") # B #result = result & "aa" # C -macro m(s:static[Td]) : stmt = +macro m(s:static[Td]) : untyped = echo get_data(s) echo get_data(s) result = newEmptyNode() @@ -77,7 +77,7 @@ proc nilcheck(): NimNode {.compileTime.} = echo(result.isNil) # true echo(repr(result)) # nil -macro testnilcheck(): stmt = +macro testnilcheck(): untyped = result = newNimNode(nnkStmtList) discard nilcheck() @@ -95,10 +95,10 @@ echo c[0] # bug #3046 -macro sampleMacroInt(i: int): stmt = +macro sampleMacroInt(i: int): untyped = echo i.intVal -macro sampleMacroBool(b: bool): stmt = +macro sampleMacroBool(b: bool): untyped = echo b.boolVal sampleMacroInt(42) diff --git a/tests/macros/tcomplexecho.nim b/tests/macros/tcomplexecho.nim index f7f933c1c..0b70a3ef7 100644 --- a/tests/macros/tcomplexecho.nim +++ b/tests/macros/tcomplexecho.nim @@ -10,7 +10,7 @@ OK import macros # Bug from the forum -macro addEcho1(s: untyped): stmt = +macro addEcho1(s: untyped): untyped = s.body.add(newCall("echo", newStrLitNode("OK"))) result = s @@ -32,7 +32,7 @@ proc foo(): seq[NimNode] {.compiletime.} = result.add test() result.add parseExpr("echo(5+56)") -macro bar(): stmt = +macro bar(): typed = result = newNimNode(nnkStmtList) let x = foo() for xx in x: diff --git a/tests/macros/tdebugstmt.nim b/tests/macros/tdebugstmt.nim index 421f8fd14..740ae7b05 100644 --- a/tests/macros/tdebugstmt.nim +++ b/tests/macros/tdebugstmt.nim @@ -6,7 +6,7 @@ x: some string''' 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 # this macro returns a list of statements: result = newNimNode(nnkStmtList, n) diff --git a/tests/macros/tdumpast2.nim b/tests/macros/tdumpast2.nim index 6b694fa77..c4c591b2a 100644 --- a/tests/macros/tdumpast2.nim +++ b/tests/macros/tdumpast2.nim @@ -21,7 +21,7 @@ proc dumpit(n: NimNode): string {.compileTime.} = add(result, dumpit(n[j])) add(result, ")") -macro dumpAST(n: stmt): stmt {.immediate.} = +macro dumpAST(n): untyped = # dump AST as a side-effect and return the inner node let n = callsite() echo dumpit(n) diff --git a/tests/macros/texprcolonexpr.nim b/tests/macros/texprcolonexpr.nim index 3b2c86b77..59c799771 100644 --- a/tests/macros/texprcolonexpr.nim +++ b/tests/macros/texprcolonexpr.nim @@ -13,7 +13,7 @@ Infix """ import macros -macro def(x: stmt): stmt {.immediate.} = +macro def(x): untyped = echo treeRepr(x) def name(a, b:cint) => nil diff --git a/tests/macros/tgensym.nim b/tests/macros/tgensym.nim index a4d1a3606..955168939 100644 --- a/tests/macros/tgensym.nim +++ b/tests/macros/tgensym.nim @@ -11,7 +11,7 @@ proc convertReturns(node, retFutureSym: NimNode): NimNode {.compileTime.} = for i in 0 .. typeDesc[proc[void, int]]''' import macros -macro showType(t:stmt): stmt = +macro showType(t:typed): untyped = let ty = t.getType echo t.repr, " => ", ty.repr diff --git a/tests/macros/typesapi2.nim b/tests/macros/typesapi2.nim index 2e59d2154..0130049c0 100644 --- a/tests/macros/typesapi2.nim +++ b/tests/macros/typesapi2.nim @@ -2,7 +2,7 @@ # be used as a type import macros -macro testTypesym (t:stmt): expr = +macro testTypesym (t:typed): untyped = var ty = t.getType if ty.typekind == ntyTypedesc: # 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)) -macro tts2 (t:stmt, idx:int): expr = +macro tts2 (t:typed, idx:int): untyped = var ty = t.getType if ty.typekind == ntyTypedesc: # skip typedesc get to the real type @@ -46,4 +46,3 @@ static: assert(tts2(TestFN2, 1) is string) assert(tts2(TestFN2, 2) is int) assert(tts2(TestFN2, 3) is float) - diff --git a/tests/manyloc/keineschweine/keineschweine.nim b/tests/manyloc/keineschweine/keineschweine.nim index 804a22852..c0f1bc031 100644 --- a/tests/manyloc/keineschweine/keineschweine.nim +++ b/tests/manyloc/keineschweine/keineschweine.nim @@ -212,9 +212,10 @@ proc free(obj: PLiveBullet) = obj.record = nil -template newExplosion(obj, animation): stmt = +template newExplosion(obj, animation) = 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)) proc explode*(b: PLiveBullet) = diff --git a/tests/metatype/tbindtypedesc.nim b/tests/metatype/tbindtypedesc.nim index 4f027407b..b287aad01 100644 --- a/tests/metatype/tbindtypedesc.nim +++ b/tests/metatype/tbindtypedesc.nim @@ -16,10 +16,10 @@ type TBar = tuple x, y: int -template accept(e: expr) = +template accept(e) = static: assert(compiles(e)) -template reject(e: expr) = +template reject(e) = static: assert(not compiles(e)) proc genericParamRepeated[T: typedesc](a: T, b: T) = diff --git a/tests/metatype/tmatrix.nim b/tests/metatype/tmatrix.nim index 5acd4389e..4fd32a932 100644 --- a/tests/metatype/tmatrix.nim +++ b/tests/metatype/tmatrix.nim @@ -9,7 +9,7 @@ type data: seq[float] 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 = result.fWidth = width diff --git a/tests/metatype/tsemistatic.nim b/tests/metatype/tsemistatic.nim index a13175ba8..3f36abde9 100644 --- a/tests/metatype/tsemistatic.nim +++ b/tests/metatype/tsemistatic.nim @@ -7,7 +7,7 @@ type semistatic[T] = static[T] or T -template isStatic*(x): expr = +template isStatic*(x): bool = compiles(static(x)) proc foo(x: semistatic[int]) = diff --git a/tests/metatype/tstatic_overloading.nim b/tests/metatype/tstatic_overloading.nim index ce51052b7..9c065e48d 100644 --- a/tests/metatype/tstatic_overloading.nim +++ b/tests/metatype/tstatic_overloading.nim @@ -5,6 +5,6 @@ import macros proc impl(op: static[int]) = echo "impl 1 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. diff --git a/tests/metatype/tstaticparammacro.nim b/tests/metatype/tstaticparammacro.nim index 5c7c5e6af..bd3295874 100644 --- a/tests/metatype/tstaticparammacro.nim +++ b/tests/metatype/tstaticparammacro.nim @@ -26,7 +26,7 @@ type const data: Tconfig = (@["aa", "bb"], @[11, 22]) -macro mymacro(data: static[TConfig]): stmt = +macro mymacro(data: static[TConfig]) = echo "letters" for s in items(data.letters): echo s @@ -44,10 +44,10 @@ const a : Ta = @[(11, 22), (33, 44)] b : Tb = (@[55,66], @[77, 88]) -macro mA(data: static[Ta]): stmt = +macro mA(data: static[Ta]) = echo "AST a \n", repr(data) -macro mB(data: static[Tb]): stmt = +macro mB(data: static[Tb]) = echo "AST b \n", repr(data) echo data.e[0] @@ -57,13 +57,13 @@ mB(b) type 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 var 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 genericMacro x diff --git a/tests/metatype/tstaticparams.nim b/tests/metatype/tstaticparams.nim index 69b62e4a6..ad6aa6589 100644 --- a/tests/metatype/tstaticparams.nim +++ b/tests/metatype/tstaticparams.nim @@ -74,7 +74,7 @@ matrix_2(tmat, ar2) matrix_3(tmat, ar1) matrix_4(tmat, ar2) -template reject(x): stmt = +template reject(x): untyped = static: assert(not compiles(x)) # test with arrays of wrong size diff --git a/tests/metatype/ttypedesc1.nim b/tests/metatype/ttypedesc1.nim index d78c62a94..e9eee581f 100644 --- a/tests/metatype/ttypedesc1.nim +++ b/tests/metatype/ttypedesc1.nim @@ -18,7 +18,7 @@ proc foo(T: typedesc[int or bool]): string = a = 10 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": # XXX: `check` needs to know that TFoo[int, float] is a type and diff --git a/tests/metatype/tymatrix.nim b/tests/metatype/tymatrix.nim index 7d3d52f85..14c4d8c88 100644 --- a/tests/metatype/tymatrix.nim +++ b/tests/metatype/tymatrix.nim @@ -1,6 +1,6 @@ import typetraits -template reject(e: expr) = +template reject(e) = static: assert(not compiles(e)) type diff --git a/tests/misc/thallo.nim b/tests/misc/thallo.nim index 17e955f03..17e6089ed 100644 --- a/tests/misc/thallo.nim +++ b/tests/misc/thallo.nim @@ -15,7 +15,7 @@ proc fac[T](x: T): T = if x <= 1: return 1 else: return x.`*`(fac(x-1)) -macro macrotest(n: expr): stmt {.immediate.} = +macro macrotest(n: varargs[untyped]): untyped = let n = callsite() expectKind(n, nnkCall) expectMinLen(n, 2) @@ -24,7 +24,7 @@ macro macrotest(n: expr): stmt {.immediate.} = result.add(newCall("write", n[1], n[i])) result.add(newCall("writeLine", n[1], newStrLitNode(""))) -macro debug(n: expr): stmt {.immediate.} = +macro debug(n: untyped): untyped {.immediate.} = let n = callsite() result = newNimNode(nnkStmtList, n) for i in 1..n.len-1: @@ -82,4 +82,3 @@ for i in 2..6: when isMainModule: {.hint: "this is the main file".} - diff --git a/tests/misc/tints.nim b/tests/misc/tints.nim index 5bfb8a17c..d5374a543 100644 --- a/tests/misc/tints.nim +++ b/tests/misc/tints.nim @@ -8,7 +8,7 @@ Success''' 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 block: const constExpr = opr(a, b) diff --git a/tests/misc/tsimplesort.nim b/tests/misc/tsimplesort.nim index 9c6ad1207..3115863d5 100644 --- a/tests/misc/tsimplesort.nim +++ b/tests/misc/tsimplesort.nim @@ -118,7 +118,7 @@ proc toTable*[A, B](pairs: openarray[tuple[key: A, result = initTable[A, B](nextPowerOfTwo(pairs.len+10)) for key, val in items(pairs): result[key] = val -template dollarImpl(): stmt = +template dollarImpl(): typed = if t.len == 0: result = "{:}" else: @@ -305,5 +305,3 @@ proc countTableTest1 = countTableTest1() echo true - - diff --git a/tests/objects/toop1.nim b/tests/objects/toop1.nim index 4727d146d..f4880e3c6 100644 --- a/tests/objects/toop1.nim +++ b/tests/objects/toop1.nim @@ -35,7 +35,7 @@ proc init(my: var TRectangle) = my.height = 10 my.draw = cast[proc (my: var TFigure) {.nimcall.}](drawRectangle) -macro `!` (n: expr): stmt {.immediate.} = +macro `!` (n: untyped): typed {.immediate.}= let n = callsite() result = newNimNode(nnkCall, n) var dot = newNimNode(nnkDotExpr, n) diff --git a/tests/overload/tparams_after_varargs.nim b/tests/overload/tparams_after_varargs.nim index a93e280b9..ad8f19ad3 100644 --- a/tests/overload/tparams_after_varargs.nim +++ b/tests/overload/tparams_after_varargs.nim @@ -1,7 +1,8 @@ discard """ output: '''a 1 b 2 x @[3, 4, 5] y 6 z 7 yay -12''' +12 +''' """ 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 -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 echo a, b -takesBlock 1, 2, "some", 0.90, "random stuff": +takesBlockA 1, 2, "some", 0.90, "random stuff": echo "yay" diff --git a/tests/overload/tspec.nim b/tests/overload/tspec.nim index f2002a390..a84bac244 100644 --- a/tests/overload/tspec.nim +++ b/tests/overload/tspec.nim @@ -71,7 +71,7 @@ var ri: ref int gen(ri) # "ref T" -template rem(x: expr) = discard +template rem(x) = discard #proc rem[T](x: T) = discard rem unresolvedExpression(undeclaredIdentifier) diff --git a/tests/overload/tstmtoverload.nim b/tests/overload/tstmtoverload.nim index 75584bcab..7c0194e60 100644 --- a/tests/overload/tstmtoverload.nim +++ b/tests/overload/tstmtoverload.nim @@ -2,17 +2,17 @@ # bug #2481 import math -template test(loopCount: int, extraI: int, testBody: stmt): stmt = +template test(loopCount: int, extraI: int, testBody: untyped): typed = block: for i in 0..loopCount-1: testBody echo "done extraI=", extraI -template test(loopCount: int, extraF: float, testBody: stmt): stmt = +template test(loopCount: int, extraF: float, testBody: untyped): typed = block: test(loopCount, round(extraF).int, testBody) -template test(loopCount: int, testBody: stmt): stmt = +template test(loopCount: int, testBody: untyped): typed = block: test(loopCount, 0, testBody) echo "done extraI passed 0" diff --git a/tests/parallel/tconvexhull.nim b/tests/parallel/tconvexhull.nim index dffe5339b..c4990bf2d 100644 --- a/tests/parallel/tconvexhull.nim +++ b/tests/parallel/tconvexhull.nim @@ -20,10 +20,10 @@ proc cmpPoint(a, b: Point): int = if result == 0: result = cmp(a.y, b.y) -template cross[T](o, a, b: T): expr = +template cross[T](o, a, b: T): untyped = (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x) -template pro(): expr = +template pro(): untyped = while lr1 > 0 and cross(result[lr1 - 1], result[lr1], p[i]) <= 0: discard result.pop lr1 -= 1 diff --git a/tests/parallel/tguard1.nim b/tests/parallel/tguard1.nim index 3e0c131c5..c7972d225 100644 --- a/tests/parallel/tguard1.nim +++ b/tests/parallel/tguard1.nim @@ -24,7 +24,7 @@ var c.i = 89 -template atomicRead(L, x): expr = +template atomicRead(L, x): untyped = {.locks: [L].}: x diff --git a/tests/parallel/tguard2.nim b/tests/parallel/tguard2.nim index b69ea3371..661893bb5 100644 --- a/tests/parallel/tguard2.nim +++ b/tests/parallel/tguard2.nim @@ -13,7 +13,7 @@ var c.i = 89 -template atomicRead(L, x): expr = +template atomicRead(L, x): untyped = {.locks: [L].}: x diff --git a/tests/parallel/tptr_to_ref.nim b/tests/parallel/tptr_to_ref.nim index 229c247ce..fee210dcd 100644 --- a/tests/parallel/tptr_to_ref.nim +++ b/tests/parallel/tptr_to_ref.nim @@ -14,7 +14,7 @@ type processes {.guard: lock.}: array[0..MAX_WORKERS-1, foreign ptr Process] # Hold a lock for a statement. -template hold(lock: Lock, body: stmt) = +template hold(lock: Lock, body: untyped) = lock.acquire defer: lock.release {.locks: [lock].}: diff --git a/tests/parser/toprprec.nim b/tests/parser/toprprec.nim index 2c22f5b80..1acd381e7 100644 --- a/tests/parser/toprprec.nim +++ b/tests/parser/toprprec.nim @@ -4,9 +4,11 @@ discard """ """ # Test operator precedence: -template `@` (x: expr): expr {.immediate.} = self.x -template `@!` (x: expr): expr {.immediate.} = x -template `===` (x: expr): expr {.immediate.} = x +template `@` (x: untyped): untyped {.immediate.} = + `self`.x + +template `@!` (x: untyped): untyped = x +template `===` (x: untyped): untyped = x type TO = object @@ -34,6 +36,3 @@ var s: TA assert init(s) == "4" echo "done" - - - diff --git a/tests/parser/tstrongspaces.nim b/tests/parser/tstrongspaces.nim index cb0219976..adab7f709 100644 --- a/tests/parser/tstrongspaces.nim +++ b/tests/parser/tstrongspaces.nim @@ -40,9 +40,9 @@ echo $foo echo (1, 2, 2) -template `&`(a, b: int): expr = a and b -template `|`(a, b: int): expr = a - b -template `++`(a, b: int): expr = a + b == 8009 +template `&`(a, b: int): int = a and b +template `|`(a, b: int): int = a - b +template `++`(a, b: int): bool = a + b == 8009 when true: let b = 66 @@ -62,7 +62,7 @@ when true: echo booA == booB -template `|`(a, b): expr = (if a.len > 0: a else: b) +template `|`(a, b): untyped = (if a.len > 0: a else: b) const tester = "tester" @@ -74,7 +74,7 @@ echo "all"|tester & " " & args # Test arrow like operators. See also tests/macros/tclosuremacro.nim proc `+->`(a, b: int): int = a + b*4 -template `===>`(a, b: int): expr = a - b shr 1 +template `===>`(a, b: int): int = a - b shr 1 echo 3 +-> 2 + 2 and 4 var arrowed = 3+->2 + 2 and 4 # arrowed = 4 diff --git a/tests/pragmas/tsym_as_pragma.nim b/tests/pragmas/tsym_as_pragma.nim index f6ba44dc9..788311244 100644 --- a/tests/pragmas/tsym_as_pragma.nim +++ b/tests/pragmas/tsym_as_pragma.nim @@ -1,7 +1,7 @@ # bug #3171 -template newDataWindow(): stmt = +template newDataWindow(): untyped = let eventClosure = proc (closure: pointer): bool {.closure, cdecl.} = discard diff --git a/tests/range/compilehelpers.nim b/tests/range/compilehelpers.nim index cb26ca5b5..08f97a5bf 100644 --- a/tests/range/compilehelpers.nim +++ b/tests/range/compilehelpers.nim @@ -1,6 +1,5 @@ -template accept(e: expr) = +template accept(e) = static: assert(compiles(e)) -template reject(e: expr) = +template reject(e) = static: assert(not compiles(e)) - diff --git a/tests/showoff/tdrdobbs_examples.nim b/tests/showoff/tdrdobbs_examples.nim index 78f711325..8687ee529 100644 --- a/tests/showoff/tdrdobbs_examples.nim +++ b/tests/showoff/tdrdobbs_examples.nim @@ -105,10 +105,10 @@ proc pat2kind(pattern: string): FormulaKind = import macros proc matchAgainst(n, pattern: NimNode): NimNode {.compileTime.} = - template `@`(current, field: expr): expr = + template `@`(current, field: untyped): untyped = newDotExpr(current, newIdentNode(astToStr(field))) - template `==@`(n, pattern: expr): expr = + template `==@`(n, pattern: untyped): untyped = newCall("==", n@kind, newIdentNode($pat2kind($pattern.ident))) case pattern.kind @@ -126,7 +126,7 @@ proc matchAgainst(n, pattern: NimNode): NimNode {.compileTime.} = else: error "invalid pattern" -macro `=~` (n: Formula, pattern: expr): bool = +macro `=~` (n: Formula, pattern: untyped): bool = result = matchAgainst(n, pattern) proc isPolyTerm2(n: Formula): bool = n =~ c * x^c diff --git a/tests/showoff/tformatopt.nim b/tests/showoff/tformatopt.nim index f33ed6921..6e790c38e 100644 --- a/tests/showoff/tformatopt.nim +++ b/tests/showoff/tformatopt.nim @@ -10,7 +10,7 @@ import macros proc invalidFormatString() = echo "invalidFormatString" -template formatImpl(handleChar: expr) = +template formatImpl(handleChar: untyped) = var i = 0 while i < f.len: if f[i] == '$': @@ -29,11 +29,11 @@ template formatImpl(handleChar: expr) = i += 1 proc `%`*(f: string, a: openArray[string]): string = - template identity(x: expr): expr = x + template identity(x: untyped): untyped = x result = "" formatImpl(identity) -macro optFormat{`%`(f, a)}(f: string{lit}, a: openArray[string]): expr = +macro optFormat{`%`(f, a)}(f: string{lit}, a: openArray[string]): untyped = result = newNimNode(nnkBracket) let f = f.strVal formatImpl(newLit) diff --git a/tests/showoff/thtml1.nim b/tests/showoff/thtml1.nim index c7a083c21..fe0cd3b1e 100644 --- a/tests/showoff/thtml1.nim +++ b/tests/showoff/thtml1.nim @@ -2,7 +2,7 @@ discard """ output: "
" """ -template htmlTag(tag: expr) {.immediate.} = +template htmlTag(tag: untyped) = proc tag(): string = "<" & astToStr(tag) & ">" htmlTag(br) diff --git a/tests/showoff/thtml2.nim b/tests/showoff/thtml2.nim index faeb4e50d..dcf6534a5 100644 --- a/tests/showoff/thtml2.nim +++ b/tests/showoff/thtml2.nim @@ -4,20 +4,20 @@ discard """ import strutils -template html(name: expr, matter: stmt) {.immediate.} = +template html(name, matter: untyped) = proc name(): string = result = "" matter result.add("") -template nestedTag(tag: expr) {.immediate.} = - template tag(matter: stmt) {.immediate.} = +template nestedTag(tag: untyped) = + template tag(matter: untyped) = result.add("<" & astToStr(tag) & ">") matter result.add("") -template simpleTag(tag: expr) {.immediate.} = - template tag(matter: expr) {.immediate.} = +template simpleTag(tag: untyped) = + template tag(matter: untyped) = result.add("<$1>$2" % [astToStr(tag), matter]) nestedTag body diff --git a/tests/showoff/tonce.nim b/tests/showoff/tonce.nim index 6fc372e87..ed2684dcf 100644 --- a/tests/showoff/tonce.nim +++ b/tests/showoff/tonce.nim @@ -5,7 +5,7 @@ new instantiation some call of p''' """ -template once(body: stmt) = +template once(body) = var x {.global.} = false if not x: x = true diff --git a/tests/showoff/tquasiquote.nim b/tests/showoff/tquasiquote.nim index ebe004a92..404712a02 100644 --- a/tests/showoff/tquasiquote.nim +++ b/tests/showoff/tquasiquote.nim @@ -4,7 +4,7 @@ discard """ import macros -macro check(ex: expr): stmt = +macro check(ex: untyped): untyped = var info = ex.lineInfo var expString = ex.toStrLit result = quote do: diff --git a/tests/specialops/tdotops.nim b/tests/specialops/tdotops.nim index ce5b3942d..bca949922 100644 --- a/tests/specialops/tdotops.nim +++ b/tests/specialops/tdotops.nim @@ -31,7 +31,7 @@ proc `.=`(x: var T1, f: string{lit}, v: int) = echo "assigning ", f, " = ", v x.x = v -template `.()`(x: T1, f: string, args: varargs[expr]): string = +template `.()`(x: T1, f: string, args: varargs[typed]): string = echo "call to ", f "dot call" @@ -63,4 +63,3 @@ echo tt.c(10) assert(not compiles(tt.d("x"))) assert(not compiles(tt.d(1, 2))) - diff --git a/tests/stdlib/tmarshal.nim b/tests/stdlib/tmarshal.nim index 6a53a2964..434caa281 100644 --- a/tests/stdlib/tmarshal.nim +++ b/tests/stdlib/tmarshal.nim @@ -9,7 +9,7 @@ omega 200 import marshal -template testit(x: expr) = discard $$to[type(x)]($$x) +template testit(x) = discard $$to[type(x)]($$x) var x: array[0..4, array[0..4, string]] = [ ["test", "1", "2", "3", "4"], ["test", "1", "2", "3", "4"], diff --git a/tests/stdlib/tnre.nim b/tests/stdlib/tnre.nim index 030319ebf..fabbb69a8 100644 --- a/tests/stdlib/tnre.nim +++ b/tests/stdlib/tnre.nim @@ -20,12 +20,13 @@ discard """ [Suite] Misc tests''' """ + import nre -import nre.init -import nre.captures -import nre.find -import nre.split -import nre.match -import nre.replace -import nre.escape -import nre.misc +import nre/init +import nre/captures +import nre/find +import nre/split +import nre/match +import nre/replace +import nre/escape +import nre/misc diff --git a/tests/stdlib/tpegs.nim b/tests/stdlib/tpegs.nim index ec839e288..e2a5a1715 100644 --- a/tests/stdlib/tpegs.nim +++ b/tests/stdlib/tpegs.nim @@ -149,7 +149,7 @@ proc addChoice(dest: var TPeg, elem: TPeg) = else: add(dest, elem) else: add(dest, elem) -template multipleOp(k: TPegKind, localOpt: expr) = +template multipleOp(k: TPegKind, localOpt) = result.kind = k result.sons = @[] for x in items(a): @@ -350,32 +350,32 @@ proc newNonTerminal*(name: string, line, column: int): PNonTerminal {. result.line = line result.col = column -template letters*: expr = +template letters*: TPeg = ## expands to ``charset({'A'..'Z', 'a'..'z'})`` charset({'A'..'Z', 'a'..'z'}) -template digits*: expr = +template digits*: TPeg = ## expands to ``charset({'0'..'9'})`` charset({'0'..'9'}) -template whitespace*: expr = +template whitespace*: TPeg = ## expands to ``charset({' ', '\9'..'\13'})`` charset({' ', '\9'..'\13'}) -template identChars*: expr = +template identChars*: TPeg = ## expands to ``charset({'a'..'z', 'A'..'Z', '0'..'9', '_'})`` charset({'a'..'z', 'A'..'Z', '0'..'9', '_'}) -template identStartChars*: expr = +template identStartChars*: TPeg = ## expands to ``charset({'A'..'Z', 'a'..'z', '_'})`` charset({'a'..'z', 'A'..'Z', '_'}) -template ident*: expr = +template ident*: TPeg = ## same as ``[a-zA-Z_][a-zA-z_0-9]*``; standard identifier sequence(charset({'a'..'z', 'A'..'Z', '_'}), *charset({'a'..'z', 'A'..'Z', '0'..'9', '_'})) -template natural*: expr = +template natural*: TPeg = ## same as ``\d+`` +digits @@ -534,10 +534,10 @@ proc bounds*(c: TCaptures, when not useUnicode: type Rune = char - template fastRuneAt(s, i, ch: expr) = + template fastRuneAt(s, i, ch) = ch = s[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 isUpper(a: char): bool {.inline.} = return a in {'A'..'Z'} @@ -847,7 +847,7 @@ proc findAll*(s: string, pattern: TPeg, start = 0): seq[string] {. ## If it does not match, @[] is returned. accumulateResult(findAll(s, pattern, start)) -template `=~`*(s: string, pattern: TPeg): expr = +template `=~`*(s: string, pattern: TPeg): untyped = ## This calls ``match`` with an implicit declared ``matches`` array that ## can be used in the scope of the ``=~`` call: ## diff --git a/tests/template/annotate.nim b/tests/template/annotate.nim index 5f395557b..a7e2f8fdb 100644 --- a/tests/template/annotate.nim +++ b/tests/template/annotate.nim @@ -1,7 +1,7 @@ import macros, parseutils # Generate tags -macro make(names: openarray[expr]): stmt {.immediate.} = +macro make(names: untyped{nkBracket}): untyped = result = newStmtList() for i in 0 .. names.len-1: diff --git a/tests/template/mcan_access_hidden_field.nim b/tests/template/mcan_access_hidden_field.nim index bf3592701..2c0026ec1 100644 --- a/tests/template/mcan_access_hidden_field.nim +++ b/tests/template/mcan_access_hidden_field.nim @@ -5,5 +5,4 @@ type proc createFoo*(a, b: int): Foo = Foo(fooa: a, foob: b) -template geta*(f: Foo): expr = f.fooa - +template geta*(f: Foo): untyped = f.fooa diff --git a/tests/template/t2do.nim b/tests/template/t2do.nim index ec364c5f3..f5f6393dc 100644 --- a/tests/template/t2do.nim +++ b/tests/template/t2do.nim @@ -7,7 +7,7 @@ discard """ proc mpf_get_d(x: int): float = float(x) proc mpf_cmp_d(a: int; b: float): int = 0 -template toFloatHelper(result: expr; tooSmall, tooLarge: stmt) {.immediate.} = +template toFloatHelper(result, tooSmall, tooLarge: untyped) = result = mpf_get_d(a) if result == 0.0 and mpf_cmp_d(a,0.0) != 0: tooSmall diff --git a/tests/template/t_otemplates.nim b/tests/template/t_otemplates.nim index 6c419f72f..6597bd37a 100644 --- a/tests/template/t_otemplates.nim +++ b/tests/template/t_otemplates.nim @@ -126,7 +126,7 @@ iterator parse_compound_statements(value, identifier: string, index: int): strin ## and returns the initialization of each as an empty statement ## i.e. if x == 5 { ... } becomes if x == 5: nil. - template get_next_ident(expected): stmt = + template get_next_ident(expected) = var nextIdent: string discard value.parseWhile(nextIdent, {'$'} + identChars, i) @@ -316,10 +316,10 @@ proc parse_template(node: NimNode, value: string) = ## Nim code into the input `node` AST. var index = 0 while index < value.len and - parse_until_symbol(node, value, index): nil + parse_until_symbol(node, value, index): discard -macro tmpli*(body: expr): stmt = +macro tmpli*(body: untyped): untyped = result = newStmtList() result.add parseExpr("result = \"\"") @@ -330,7 +330,7 @@ macro tmpli*(body: expr): stmt = parse_template(result, reindent(value)) -macro tmpl*(body: expr): stmt = +macro tmpl*(body: untyped): untyped = result = newStmtList() var value = if body.kind in nnkStrLit..nnkTripleStrLit: body.strVal diff --git a/tests/template/tdefault_nil.nim b/tests/template/tdefault_nil.nim index 891166306..c5c372d9e 100644 --- a/tests/template/tdefault_nil.nim +++ b/tests/template/tdefault_nil.nim @@ -2,7 +2,7 @@ # bug #2629 import sequtils, os -template glob_rst(basedir: string = nil): expr = +template glob_rst(basedir: string = nil): untyped = if baseDir.isNil: to_seq(walk_files("*.rst")) else: diff --git a/tests/template/thygienictempl.nim b/tests/template/thygienictempl.nim index 5e4f534f8..de40450aa 100644 --- a/tests/template/thygienictempl.nim +++ b/tests/template/thygienictempl.nim @@ -2,7 +2,7 @@ var e = "abc" -raise newException(EIO, e & "ha!") +raise newException(IOError, e & "ha!") template t() = echo(foo) @@ -10,7 +10,7 @@ var foo = 12 t() -template test_in(a, b, c: expr): bool {.immediate, dirty.} = +template test_in(a, b, c: untyped): bool {.dirty.} = var result {.gensym.}: bool = false false diff --git a/tests/template/tissue909.nim b/tests/template/tissue909.nim index 5b57a3558..6786ff48c 100644 --- a/tests/template/tissue909.nim +++ b/tests/template/tissue909.nim @@ -8,7 +8,7 @@ template baz() = var y = foo discard y() -macro test(): stmt = +macro test(): untyped = result = getAst(baz()) echo(treeRepr(result)) diff --git a/tests/template/tissue993.nim b/tests/template/tissue993.nim index dae9df683..552890bb4 100644 --- a/tests/template/tissue993.nim +++ b/tests/template/tissue993.nim @@ -1,15 +1,15 @@ type PNode* = ref object of RootObj -template litNode (name, ty): stmt = +template litNode(name, ty) = type name* = ref object of PNode val*: ty litNode PIntNode, int import json -template withKey*(j: JsonNode; key: string; varname: expr; - body:stmt): stmt {.immediate.} = +template withKey*(j: JsonNode; key: string; varname, + body: untyped): typed = if j.hasKey(key): let varname{.inject.}= j[key] block: @@ -18,4 +18,3 @@ template withKey*(j: JsonNode; key: string; varname: expr; var j = parsejson("{\"zzz\":1}") withkey(j, "foo", x): echo(x) - diff --git a/tests/template/tit.nim b/tests/template/tit.nim index cf50d2f6f..76b1d151b 100644 --- a/tests/template/tit.nim +++ b/tests/template/tit.nim @@ -1,7 +1,7 @@ # bug #1337 -template someIt(a, pred: expr): expr = +template someIt(a, pred): untyped = var it {.inject.} = 0 pred diff --git a/tests/template/tparams_gensymed.nim b/tests/template/tparams_gensymed.nim index 568725fd4..3fb0dd4a5 100644 --- a/tests/template/tparams_gensymed.nim +++ b/tests/template/tparams_gensymed.nim @@ -43,7 +43,7 @@ template forStatic(index, slice, predicate: untyped) = block: const index = i predicate - template iterateStartingFrom(i: int): stmt = + template iterateStartingFrom(i: int) = when i <= b: iteration i iterateStartingFrom i + 1 diff --git a/tests/template/tprefer_immediate.nim b/tests/template/tprefer_immediate.nim index 578f447b0..3a4cfc07b 100644 --- a/tests/template/tprefer_immediate.nim +++ b/tests/template/tprefer_immediate.nim @@ -4,14 +4,12 @@ discard """ # Test that immediate templates are preferred over non-immediate templates -template foo(a, b: expr) = echo "foo expr" - +template foo(a, b: untyped) = echo "foo expr" template foo(a, b: int) = echo "foo int" template foo(a, b: float) = echo "foo float" template foo(a, b: string) = echo "foo string" -template foo(a, b: expr) {.immediate.} = echo "immediate" +template foo(a, b: untyped) {.immediate.} = echo "immediate" template foo(a, b: bool) = echo "foo bool" template foo(a, b: char) = echo "foo char" foo(undeclaredIdentifier, undeclaredIdentifier2) - diff --git a/tests/template/tscope.nim b/tests/template/tscope.nim index 2d5841af3..1eeebbdd4 100644 --- a/tests/template/tscope.nim +++ b/tests/template/tscope.nim @@ -3,7 +3,7 @@ discard """ """ var x = 1 -template quantity(): stmt {.immediate.} = +template quantity() = # Causes internal error in compiler/sem.nim proc unit*(x = 1.0): float = 12 # Throws the correct error: redefinition of 'x' diff --git a/tests/template/tstmt_semchecked_twice.nim b/tests/template/tstmt_semchecked_twice.nim index 05c16c3c9..c6463ae06 100644 --- a/tests/template/tstmt_semchecked_twice.nim +++ b/tests/template/tstmt_semchecked_twice.nim @@ -13,7 +13,7 @@ type Vector2[T] = T Pixels=int -template use*(fb: int, st: stmt) : stmt = +template use*(fb: int, st: untyped): untyped = echo "a ", $fb st echo "a ", $fb diff --git a/tests/template/tsymchoicefield.nim b/tests/template/tsymchoicefield.nim index ab05500bf..4483c2aa2 100644 --- a/tests/template/tsymchoicefield.nim +++ b/tests/template/tsymchoicefield.nim @@ -3,10 +3,9 @@ type Foo = object var f = Foo(len: 40) -template getLen(f: Foo): expr = f.len +template getLen(f: Foo): int = f.len echo f.getLen # This fails, because `len` gets the nkOpenSymChoice # treatment inside the template early pass and then # it can't be recognized as a field anymore - diff --git a/tests/template/ttempl3.nim b/tests/template/ttempl3.nim index 56daf9fe6..91d416c48 100644 --- a/tests/template/ttempl3.nim +++ b/tests/template/ttempl3.nim @@ -1,6 +1,6 @@ -template withOpenFile(f: expr, filename: string, mode: TFileMode, - actions: stmt): stmt {.immediate.} = +template withOpenFile(f: untyped, filename: string, mode: TFileMode, + actions: untyped): untyped = block: # test that 'f' is implicitly 'injecting': var f: TFile @@ -20,20 +20,20 @@ var myVar: array[0..1, int] # Test zero argument template: -template ha: expr = myVar[0] +template ha: untyped = myVar[0] ha = 1 echo(ha) # Test identifier generation: -template prefix(name: expr): expr {.immediate.} = `"hu" name` +template prefix(name): untyped = `"hu" name` var `hu "XYZ"` = "yay" echo prefix(XYZ) -template typedef(name: expr, typ: typeDesc) {.immediate, dirty.} = +template typedef(name: untyped, typ: typeDesc) {.immediate, dirty.} = type `T name`* = typ `P name`* = ref `T name` @@ -51,7 +51,7 @@ type proc initFoo(arg: int): Foo = result.arg = arg -template create(typ: typeDesc, arg: expr): expr = `init typ`(arg) +template create(typ: typeDesc, arg: untyped): untyped = `init typ`(arg) var ff = Foo.create(12) diff --git a/tests/template/ttempl4.nim b/tests/template/ttempl4.nim index 26c82e471..d1d26385f 100644 --- a/tests/template/ttempl4.nim +++ b/tests/template/ttempl4.nim @@ -1,8 +1,7 @@ -template `:=`(name, val: expr): stmt {.immediate.} = +template `:=`(name, val: untyped): typed = var name = val ha := 1 * 4 hu := "ta-da" == "ta-da" echo ha, hu - diff --git a/tests/template/ttempl5.nim b/tests/template/ttempl5.nim index a020a8e2c..fd3ea0cad 100644 --- a/tests/template/ttempl5.nim +++ b/tests/template/ttempl5.nim @@ -9,7 +9,7 @@ proc parse_to_close(value: string, index: int, open='(', close=')'): int = discard # Call parse_to_close -template get_next_ident: stmt = +template get_next_ident: typed = discard "{something}".parse_to_close(0, open = '{', close = '}') get_next_ident() @@ -19,11 +19,10 @@ get_next_ident() #bug #880 (also example in the manual!) -template typedef(name: expr, typ: typedesc) {.immediate.} = +template typedef(name: untyped, typ: typedesc) = type `T name`* {.inject.} = typ `P name`* {.inject.} = ref `T name` typedef(myint, int) var x: PMyInt - diff --git a/tests/template/twhen_gensym.nim b/tests/template/twhen_gensym.nim index d84ee6f03..f1a8d0eb7 100644 --- a/tests/template/twhen_gensym.nim +++ b/tests/template/twhen_gensym.nim @@ -3,7 +3,7 @@ discard """ """ # bug #2670 -template testTemplate(b: bool): stmt = +template testTemplate(b: bool): typed = when b: var a = "hi" else: diff --git a/tests/template/twrongmapit.nim b/tests/template/twrongmapit.nim index df695fcd6..cbc63b9cd 100644 --- a/tests/template/twrongmapit.nim +++ b/tests/template/twrongmapit.nim @@ -8,7 +8,7 @@ discard """ type Foo* {.pure, final.} = object elt: float -template defineOpAssign(T: expr, op: expr) {.immediate.} = +template defineOpAssign(T, op: untyped) {.immediate.} = proc op*(v: var T, w: T) {.inline.} = for i in 0..1: op(v.elt, w.elt) @@ -18,7 +18,7 @@ const ATTEMPT = 0 when ATTEMPT == 0: # FAILS: defining `/=` with template calling template # ERROR about sem.nim line 144 - template defineOpAssigns(T: expr) {.immediate.} = + template defineOpAssigns(T: untyped) = mixin `/=` defineOpAssign(T, `/=`) diff --git a/tests/template/twrongsymkind.nim b/tests/template/twrongsymkind.nim index be3d8c652..5fa618914 100644 --- a/tests/template/twrongsymkind.nim +++ b/tests/template/twrongsymkind.nim @@ -9,7 +9,7 @@ type MyData = object x: int -template newDataWindow(data: ref MyData): stmt = +template newDataWindow(data: ref MyData): untyped = proc testProc(data: ref MyData) = echo "Hello, ", data.x testProc(data) diff --git a/tests/template/utemplates.nim b/tests/template/utemplates.nim index 8b9ae5d26..199268046 100644 --- a/tests/template/utemplates.nim +++ b/tests/template/utemplates.nim @@ -1,32 +1,31 @@ import unittest -template t(a: int): expr = "int" -template t(a: string): expr = "string" +template t(a: int): string = "int" +template t(a: string): string = "string" test "templates can be overloaded": check t(10) == "int" check t("test") == "string" test "previous definitions can be further overloaded or hidden in local scopes": - template t(a: bool): expr = "bool" + template t(a: bool): string = "bool" check t(true) == "bool" check t(10) == "int" - template t(a: int): expr = "inner int" + template t(a: int): string = "inner int" check t(10) == "inner int" check t("test") == "string" test "templates can be redefined multiple times": - template customAssert(cond: bool, msg: string): stmt {.immediate, dirty.} = + template customAssert(cond: bool, msg: string): typed {.immediate, dirty.} = if not cond: fail(msg) - template assertion_failed(body: stmt) {.immediate, dirty.} = - template fail(msg: string): stmt = body + template assertion_failed(body: typed) {.immediate, dirty.} = + template fail(msg: string): typed = body assertion_failed: check msg == "first fail path" customAssert false, "first fail path" assertion_failed: check msg == "second fail path" customAssert false, "second fail path" - diff --git a/tests/trmacros/targlist.nim b/tests/trmacros/targlist.nim index f9d2cb6c6..46235dab1 100644 --- a/tests/trmacros/targlist.nim +++ b/tests/trmacros/targlist.nim @@ -3,7 +3,7 @@ discard """ """ proc f(x: varargs[string, `$`]) = discard -template optF{f(x)}(x: varargs[expr]) = +template optF{f(x)}(x: varargs[untyped]) = writeLine(stdout, x) f 1, 2, false, 3, "ha" diff --git a/tests/trmacros/tcse.nim b/tests/trmacros/tcse.nim index 023a8f298..315570d8f 100644 --- a/tests/trmacros/tcse.nim +++ b/tests/trmacros/tcse.nim @@ -2,8 +2,8 @@ discard """ output: "4" """ -template cse{f(a, a, x)}(a: expr{(nkDotExpr|call|nkBracketExpr)&noSideEffect}, - f: expr, x: varargs[expr]): expr = +template cse{f(a, a, x)}(a: typed{(nkDotExpr|call|nkBracketExpr)&noSideEffect}, + f: typed, x: varargs[typed]): untyped = let aa = a f(aa, aa, x)+4 diff --git a/tests/trmacros/tmatrix.nim b/tests/trmacros/tmatrix.nim index f409434c5..a14ad2db0 100644 --- a/tests/trmacros/tmatrix.nim +++ b/tests/trmacros/tmatrix.nim @@ -15,7 +15,7 @@ proc `$`(a: TMat): string = result = $a.dummy proc mat21(): TMat = result.dummy = 21 -macro optOps{ (`+`|`-`|`*`) ** a }(a: TMat): expr = +macro optOps{ (`+`|`-`|`*`) ** a }(a: TMat): untyped = echo treeRepr(a) result = newCall(bindSym"mat21") diff --git a/tests/trmacros/tnoalias.nim b/tests/trmacros/tnoalias.nim index 1d5671362..ec12d4712 100644 --- a/tests/trmacros/tnoalias.nim +++ b/tests/trmacros/tnoalias.nim @@ -2,7 +2,7 @@ discard """ output: "23" """ -template optslice{a = b + c}(a: expr{noalias}, b, c: expr): stmt = +template optslice{a = b + c}(a: untyped{noalias}, b, c: untyped): typed = a = b inc a, c diff --git a/tests/trmacros/tnoalias2.nim b/tests/trmacros/tnoalias2.nim index 5a816acb9..9362e764f 100644 --- a/tests/trmacros/tnoalias2.nim +++ b/tests/trmacros/tnoalias2.nim @@ -3,7 +3,7 @@ discard """ """ # bug #206 -template optimizeOut{testFunc(a, b)}(a: int, b: int{alias}) : expr = 0 +template optimizeOut{testFunc(a, b)}(a: int, b: int{alias}): untyped = 0 proc testFunc(a, b: int): int = result = a + b var testVar = 1 diff --git a/tests/trmacros/tnoendlessrec.nim b/tests/trmacros/tnoendlessrec.nim index 53891bcc0..508770ca7 100644 --- a/tests/trmacros/tnoendlessrec.nim +++ b/tests/trmacros/tnoendlessrec.nim @@ -4,7 +4,7 @@ discard """ # test that an endless recursion is avoided: -template optLen{len(x)}(x: expr): expr = len(x) +template optLen{len(x)}(x: typed): int = len(x) var s = "lala" echo len(s) diff --git a/tests/trmacros/tor.nim b/tests/trmacros/tor.nim index 500851582..d698e928d 100644 --- a/tests/trmacros/tor.nim +++ b/tests/trmacros/tor.nim @@ -4,13 +4,13 @@ true 3''' """ -template arithOps: expr = (`+` | `-` | `*`) -template testOr{ (arithOps{f})(a, b) }(a, b, f: expr): expr = f(a+1, b) +template arithOps: untyped = (`+` | `-` | `*`) +template testOr{ (arithOps{f})(a, b) }(a, b, f: untyped): untyped = f(a+1, b) let xx = 10 echo 10*xx -template t{x = (~x){y} and (~x){z}}(x, y, z: bool): stmt = +template t{x = (~x){y} and (~x){z}}(x, y, z: bool): typed = x = y if x: x = z @@ -22,7 +22,7 @@ a = b and a echo a # bug #798 -template t012{(0|1|2){x}}(x: expr): expr = x+1 +template t012{(0|1|2){x}}(x: untyped): untyped = x+1 let z = 1 # outputs 3 thanks to fixpoint iteration: echo z diff --git a/tests/trmacros/tpartial.nim b/tests/trmacros/tpartial.nim index fdaa3414a..c636684d7 100644 --- a/tests/trmacros/tpartial.nim +++ b/tests/trmacros/tpartial.nim @@ -5,7 +5,7 @@ discard """ proc p(x, y: int; cond: bool): int = result = if cond: x + y else: x - y -template optP{p(x, y, true)}(x, y: expr): expr = x - y -template optP{p(x, y, false)}(x, y: expr): expr = x + y +template optP{p(x, y, true)}(x, y): untyped = x - y +template optP{p(x, y, false)}(x, y): untyped = x + y echo p(2, 4, true) diff --git a/tests/trmacros/tstar.nim b/tests/trmacros/tstar.nim index 536289ff0..86f698232 100644 --- a/tests/trmacros/tstar.nim +++ b/tests/trmacros/tstar.nim @@ -10,7 +10,7 @@ proc `&&`(s: varargs[string]): string = for i in 1..len(s)-1: result.add s[i] inc calls -template optConc{ `&&` * a }(a: string): expr = &&a +template optConc{ `&&` * a }(a: string): string = &&a let space = " " echo "my" && (space & "awe" && "some " ) && "concat" diff --git a/tests/trmacros/tstmtlist.nim b/tests/trmacros/tstmtlist.nim index 5202f778b..751acb79a 100644 --- a/tests/trmacros/tstmtlist.nim +++ b/tests/trmacros/tstmtlist.nim @@ -8,7 +8,7 @@ discard """ template optWrite{ write(f, x) ((write|writeLine){w})(f, y) -}(x, y: varargs[expr], f, w: expr) = +}(x, y: varargs[untyped], f, w: untyped) = w(f, "|", x, y, "|") if true: diff --git a/tests/tuples/tuple_with_nil.nim b/tests/tuples/tuple_with_nil.nim index 9b5d583d3..7f5a359f5 100644 --- a/tests/tuples/tuple_with_nil.nim +++ b/tests/tuples/tuple_with_nil.nim @@ -758,7 +758,7 @@ proc addfmtfmt(fmtstr: string; args: NimNode; retvar: NimNode): NimNode {.compil if arg.cnt == 0: warning("Argument " & $(i+1) & " `" & args[i].repr & "` is not used in format string") -macro addfmt(s: var string, fmtstr: string{lit}, args: varargs[expr]): expr = +macro addfmt(s: var string, fmtstr: string{lit}, args: varargs[typed]): untyped = ## The same as `s.add(fmtstr.fmt(args...))` but faster. result = addfmtfmt($fmtstr, args, s) diff --git a/tests/typerel/temptynode.nim b/tests/typerel/temptynode.nim index b32b16121..32148ce13 100644 --- a/tests/typerel/temptynode.nim +++ b/tests/typerel/temptynode.nim @@ -10,7 +10,7 @@ import macros proc blah(x: proc (a, b: int): int) = echo x(5, 5) -macro test(): stmt = +macro test(): untyped = result = newNimNode(nnkEmpty) blah(test()) diff --git a/tests/typerel/tsymchoice_for_expr.nim b/tests/typerel/tsymchoice_for_expr.nim index 4c1f52bef..394b22704 100644 --- a/tests/typerel/tsymchoice_for_expr.nim +++ b/tests/typerel/tsymchoice_for_expr.nim @@ -1,6 +1,6 @@ # bug #1988 -template t(e: expr) = discard +template t(e) = discard proc positive(x: int): int = +x proc negative(x: int): int = -x diff --git a/tests/typerel/tvarargsexpr.nim b/tests/typerel/tvarargsexpr.nim index c6a59fb20..092d50076 100644 --- a/tests/typerel/tvarargsexpr.nim +++ b/tests/typerel/tvarargsexpr.nim @@ -8,7 +8,7 @@ true''' import macros -macro thirteen(args: varargs[expr]): expr = +macro thirteen(args: varargs[untyped]): int = result = newIntLitNode(13) doAssert(13==thirteen([1,2])) # works @@ -22,7 +22,8 @@ echo "success" # bug #2545 import macros -macro test(e: varargs[untyped]): expr = bindSym"true" +macro test(e: varargs[untyped]): untyped = + bindSym"true" echo test(a) echo test(fake=90, arguments=80, also="false", possible=true) diff --git a/tests/types/tauto_canbe_void.nim b/tests/types/tauto_canbe_void.nim index 60e83c510..fd42cb701 100644 --- a/tests/types/tauto_canbe_void.nim +++ b/tests/types/tauto_canbe_void.nim @@ -1,7 +1,7 @@ import future -template tempo(s: expr) = +template tempo(s) = s("arg") tempo((s: string)->auto => echo(s)) diff --git a/tests/types/tisopr.nim b/tests/types/tisopr.nim index 14999ebee..2f9dbf245 100644 --- a/tests/types/tisopr.nim +++ b/tests/types/tisopr.nim @@ -17,10 +17,10 @@ proc IsVoid[T](): string = const x = int is int echo x, " ", float is float, " ", float is string, " ", IsVoid[void]() -template yes(e: expr): stmt = +template yes(e): void = static: assert e -template no(e: expr): stmt = +template no(e): void = static: assert(not e) when false: diff --git a/tests/usingstmt/tusingstatement.nim b/tests/usingstmt/tusingstatement.nim index 0d76b2423..8585bcc9e 100644 --- a/tests/usingstmt/tusingstatement.nim +++ b/tests/usingstmt/tusingstatement.nim @@ -12,7 +12,7 @@ import # Nim's destructors offer a mechanism for automatic # disposal of resources. # -macro autoClose(e: expr): stmt {.immediate.} = +macro autoClose(args: varargs[untyped]): untyped = let e = callsite() if e.len != 3: error "Using statement: unexpected number of arguments. Got " & @@ -85,5 +85,3 @@ proc use(r: var TResource) = autoClose(r = openResource("test")): use r - - diff --git a/tests/vm/tanonproc.nim b/tests/vm/tanonproc.nim index 474b768ca..c5cb57d75 100644 --- a/tests/vm/tanonproc.nim +++ b/tests/vm/tanonproc.nim @@ -42,7 +42,7 @@ proc getOrElse[T](o: Option[T], def: T): T = proc quoteStr(s: string): Option[string] = s.some.notEmpty.map(v => "`" & v & "`") -macro str(s: string): stmt = +macro str(s: string): typed = let x = s.strVal let y = quoteStr(x) let sn = newStrLitNode(y.getOrElse("NONE")) diff --git a/tests/vm/tasmparser.nim b/tests/vm/tasmparser.nim index fbacdbc87..d70c629b6 100644 --- a/tests/vm/tasmparser.nim +++ b/tests/vm/tasmparser.nim @@ -10,10 +10,10 @@ var cpp {.compileTime.} = "" token {.compileTime.} = "" -proc log (msg: string) {.compileTime.} = +proc log(msg: string) {.compileTime.} = echo msg -proc asmx64 () {.compileTime} = +proc asmx64() {.compileTime} = #log "code = $1" % code @@ -36,7 +36,7 @@ proc asmx64 () {.compileTime} = const end_or_symbol_or_comment_or_passthrough = symbolStart + end_or_comment + passthrough_start - proc abortAsmParse (err:string) = + proc abortAsmParse(err:string) = discard let codeLen = code.len @@ -49,17 +49,17 @@ proc asmx64 () {.compileTime} = var state:asmParseState = leading - proc checkEnd (err:string) = - let ch = code [start] - if int (ch) == 0: - abortAsmParse (err) + proc checkEnd(err:string) = + let ch = code[start] + if int(ch) == 0: + abortAsmParse(err) - proc get_passthrough () = + proc get_passthrough() = inc start let prev_start = start let prev_token = token - start += code.parseUntil (token, passthrough_end, start) - checkEnd ("Failed to find passthrough end delimiter from offset $1 for:$2\n$3" % [$prev_start, $(code [prev_start-prev_token.len..prev_start]), token[1..token.len-1]]) + start += code.parseUntil(token, passthrough_end, start) + checkEnd("Failed to find passthrough end delimiter from offset $1 for:$2\n$3" % [$prev_start, $(code[prev_start-prev_token.len..prev_start]), token[1..token.len-1]]) inc start cpp.add "`" cpp.add token @@ -67,27 +67,27 @@ proc asmx64 () {.compileTime} = var inparse = true - proc checkCmdEnd () = + proc checkCmdEnd() = if codeLen == start: state = endCmd inparse = false while inparse: - checkCmdEnd () + checkCmdEnd() - log ("state=$1 start=$2" % [$state, $start]) + log("state=$1 start=$2" % [$state, $start]) case state: of leading: echo "b100 ", start - start += code.skipWhile (leadingWhiteSpace, start) + start += code.skipWhile(leadingWhiteSpace, start) echo "b200 ", start - let ch = code [start] + let ch = code[start] if ch in endOfLine: - inc (line) + inc(line) #echo "c100 ", start, ' ', code - start += code.skipWhile (endOfline, start) + start += code.skipWhile(endOfline, start) #echo "c200 ", start, ' ', code continue elif ch in symbolStart: @@ -95,20 +95,20 @@ proc asmx64 () {.compileTime} = elif ch in eolComment: state = skipToEndOfLine elif ch in passthrough_start: - get_passthrough () + get_passthrough() echo "d100 ", start - start += code.parseUntil (token, end_or_symbol_or_comment_or_passthrough, start) + start += code.parseUntil(token, end_or_symbol_or_comment_or_passthrough, start) echo "d200 ", start cpp.add token state = mnemonic - elif int (ch) == 0: + elif int(ch) == 0: break else: - abortAsmParse ("after '$3' illegal character at offset $1: $2" % [$start, $(int (ch)), token]) + abortAsmParse("after '$3' illegal character at offset $1: $2" % [$start, $(int(ch)), token]) of mnemonic: echo "e100 ", start - start += code.parseWhile (token, symbol, start) + start += code.parseWhile(token, symbol, start) echo "e200 ", start cpp.add xp cpp.add token @@ -118,29 +118,29 @@ proc asmx64 () {.compileTime} = of betweenArguments: let tmp = start let rcode = code - start += rcode.parseUntil (token, end_or_symbol_or_comment_or_passthrough, tmp) + start += rcode.parseUntil(token, end_or_symbol_or_comment_or_passthrough, tmp) cpp.add token if codeLen <= start: state = endCmd continue - let ch = code [start] + let ch = code[start] if ch in passthrough_start: - get_passthrough () + get_passthrough() continue - if (ch in {'x', 'X'}) and ('0' == code [start-1]): - token = $(code [start]) + if(ch in {'x', 'X'}) and('0' == code[start-1]): + token = $(code[start]) cpp.add token inc start continue state = arguments of arguments: - if code [start] in end_or_comment: + if code[start] in end_or_comment: state = endCmd continue - start += code.parseWhile (token, symbol, start) + start += code.parseWhile(token, symbol, start) cpp.add xp cpp.add token state = betweenArguments @@ -151,21 +151,21 @@ proc asmx64 () {.compileTime} = of skipToEndOfLine: echo "a100 ", start - start += code.skipUntil (endOfLine, start) + start += code.skipUntil(endOfLine, start) echo "a200 ", start - start += code.skipWhile (endOfline, start) + start += code.skipWhile(endOfline, start) echo "a300 ", start inc line state = leading cpp.add asmx64post - echo ($cpp) + echo($cpp) -macro asmx64x (code_in:expr) : stmt = +macro asmx64x(code_in:untyped) : typed = code = $code_in - echo ("code.len = $1, code = >>>$2<<<" % [$code.len, code]) - asmx64 () + echo("code.len = $1, code = >>>$2<<<" % [$code.len, code]) + asmx64() discard result asmx64x """ diff --git a/tests/vm/tcomponent.nim b/tests/vm/tcomponent.nim index efeba2a6d..e7962e7ab 100644 --- a/tests/vm/tcomponent.nim +++ b/tests/vm/tcomponent.nim @@ -70,12 +70,12 @@ proc parse_component(body: NimNode): Component = result.procs_index.add(procdef.identifier.name) else: discard -macro component*(name: expr, body: stmt): stmt {.immediate.} = +macro component*(name, body: untyped): typed = let component = parse_component(body) registry.addComponent($name, component) parseStmt("discard") -macro component_builtins(body: stmt): stmt {.immediate.} = +macro component_builtins(body: untyped): typed = let builtin = parse_component(body) registry.field_index = builtin.field_index registry.procs_index = builtin.procs_index @@ -88,7 +88,7 @@ proc bind_methods*(component: var Component, identifier: Ident): seq[NimNode] = procdef.params.insert(this_field, 0) result.add(procdef.render()) -macro bind_components*(type_name, component_names: expr): stmt {.immediate.} = +macro bind_components*(type_name, component_names: untyped): typed = result = newStmtList() let identifier = newIdent(type_name) let components = newBracket(component_names) diff --git a/tests/vm/teval1.nim b/tests/vm/teval1.nim index 1d3a68a0d..0eaa050da 100644 --- a/tests/vm/teval1.nim +++ b/tests/vm/teval1.nim @@ -5,7 +5,7 @@ proc testProc: string {.compileTime.} = result = result & "" when true: - macro test(n: stmt): stmt {.immediate.} = + macro test(n: untyped): untyped = result = newNimNode(nnkStmtList) echo "#", testProc(), "#" test: @@ -20,5 +20,3 @@ echo "##", x, "##" static: var i, j: set[int8] = {} var k = i + j - - diff --git a/tests/vm/texcl.nim b/tests/vm/texcl.nim index 4ccfd6bfa..e23a423fe 100644 --- a/tests/vm/texcl.nim +++ b/tests/vm/texcl.nim @@ -15,13 +15,13 @@ proc initOpts(): set[nlOptions] = result.incl nloDebug result.incl nloNone result.excl nloDebug - + const cOpts = initOpts() -macro nlo(): stmt = +macro nlo(): typed = nlOpts.incl(nloNone) nlOpts.excl(nloDebug) result = newEmptyNode() nlo() -echo nloDebug in cOpts \ No newline at end of file +echo nloDebug in cOpts diff --git a/tests/vm/tmitems.nim b/tests/vm/tmitems.nim index 4ee225eed..a77c3fb23 100644 --- a/tests/vm/tmitems.nim +++ b/tests/vm/tmitems.nim @@ -7,7 +7,7 @@ discard """ # bug #3731 var list {.compileTime.} = newSeq[int]() -macro calc*(): stmt {.immediate.} = +macro calc*(): typed = list.add(1) for c in list.mitems: c = 13 @@ -19,7 +19,7 @@ calc() # bug #3859 import macros -macro m: stmt = +macro m: typed = var s = newseq[NimNode](3) # var s: array[3,NimNode] # not working either for i in 0.. Date: Thu, 3 Aug 2017 17:37:02 +0100 Subject: Add mips64 and mips64el CPU platforms (#5866) --- compiler/installer.ini | 2 +- compiler/platform.nim | 7 +++++-- lib/posix/posix_other.nim | 3 ++- lib/system.nim | 2 +- lib/system/platforms.nim | 4 ++++ tools/niminst/buildsh.tmpl | 10 +++++++++- tools/niminst/makefile.tmpl | 7 +++++-- 7 files changed, 27 insertions(+), 8 deletions(-) (limited to 'lib/system.nim') diff --git a/compiler/installer.ini b/compiler/installer.ini index 8cc89da9f..680a5f9d5 100644 --- a/compiler/installer.ini +++ b/compiler/installer.ini @@ -6,7 +6,7 @@ Name: "Nim" Version: "$version" Platforms: """ windows: i386;amd64 - linux: i386;amd64;powerpc64;arm;sparc;mips;mipsel;powerpc;powerpc64el;arm64 + linux: i386;amd64;powerpc64;arm;sparc;mips;mipsel;mips64;mips64el;powerpc;powerpc64el;arm64 macosx: i386;amd64;powerpc64 solaris: i386;amd64;sparc;sparc64 freebsd: i386;amd64 diff --git a/compiler/platform.nim b/compiler/platform.nim index eb0aca186..e8b80ab9c 100644 --- a/compiler/platform.nim +++ b/compiler/platform.nim @@ -171,7 +171,8 @@ type # alias conditionals to condsyms (end of module). cpuNone, cpuI386, cpuM68k, cpuAlpha, cpuPowerpc, cpuPowerpc64, cpuPowerpc64el, cpuSparc, cpuVm, cpuIa64, cpuAmd64, cpuMips, cpuMipsel, - cpuArm, cpuArm64, cpuJS, cpuNimrodVM, cpuAVR, cpuMSP430, cpuSparc64 + cpuArm, cpuArm64, cpuJS, cpuNimrodVM, cpuAVR, cpuMSP430, cpuSparc64, + cpuMips64, cpuMips64el type TEndian* = enum @@ -200,7 +201,9 @@ const (name: "nimrodvm", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32), (name: "avr", intSize: 16, endian: littleEndian, floatSize: 32, bit: 16), (name: "msp430", intSize: 16, endian: littleEndian, floatSize: 32, bit: 16), - (name: "sparc64", intSize: 64, endian: bigEndian, floatSize: 64, bit: 64)] + (name: "sparc64", intSize: 64, endian: bigEndian, floatSize: 64, bit: 64), + (name: "mips64", intSize: 64, endian: bigEndian, floatSize: 64, bit: 64), + (name: "mips64el", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64)] var targetCPU*, hostCPU*: TSystemCPU diff --git a/lib/posix/posix_other.nim b/lib/posix/posix_other.nim index 1d50f2bac..9629b399e 100644 --- a/lib/posix/posix_other.nim +++ b/lib/posix/posix_other.nim @@ -572,7 +572,8 @@ else: MAP_POPULATE*: cint = 0 when defined(linux) or defined(nimdoc): - when defined(alpha) or defined(mips) or defined(parisc) or + when defined(alpha) or defined(mips) or defined(mipsel) or + defined(mips64) or defined(mips64el) or defined(parisc) or defined(sparc) or defined(nimdoc): const SO_REUSEPORT* = cint(0x0200) ## Multiple binding: load balancing on incoming TCP connections diff --git a/lib/system.nim b/lib/system.nim index f84a47df0..e6d961a35 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1313,7 +1313,7 @@ const hostCPU* {.magic: "HostCPU".}: string = "" ## a string that describes the host CPU. Possible values: ## "i386", "alpha", "powerpc", "powerpc64", "powerpc64el", "sparc", - ## "amd64", "mips", "mipsel", "arm", "arm64". + ## "amd64", "mips", "mipsel", "arm", "arm64", "mips64", "mips64el". seqShallowFlag = low(int) diff --git a/lib/system/platforms.nim b/lib/system/platforms.nim index eeada5c51..9bdbbaa59 100644 --- a/lib/system/platforms.nim +++ b/lib/system/platforms.nim @@ -24,6 +24,8 @@ type amd64, ## x86_64 (AMD64); 64 bit x86 compatible CPU mips, ## Mips based processor mipsel, ## Little Endian Mips based processor + mips64, ## 64-bit MIPS processor + mips64el, ## Little Endian 64-bit MIPS processor arm, ## ARM based processor arm64, ## ARM64 based processor vm, ## Some Virtual machine: Nim's VM or JavaScript @@ -73,6 +75,8 @@ const elif defined(amd64): CpuPlatform.amd64 elif defined(mips): CpuPlatform.mips elif defined(mipsel): CpuPlatform.mipsel + elif defined(mips64): CpuPlatform.mips64 + elif defined(mips64el): CpuPlatform.mips64el elif defined(arm): CpuPlatform.arm elif defined(arm64): CpuPlatform.arm64 elif defined(vm): CpuPlatform.vm diff --git a/tools/niminst/buildsh.tmpl b/tools/niminst/buildsh.tmpl index e90ad97c0..956c5ead8 100644 --- a/tools/niminst/buildsh.tmpl +++ b/tools/niminst/buildsh.tmpl @@ -123,7 +123,15 @@ case $ucpu in *power*|*ppc* ) mycpu="powerpc" ;; *mips* ) - mycpu="mips" ;; + mycpu="$("$CC" -dumpmachine | sed 's/-.*//')" + case $mycpu in + mips|mipsel|mips64|mips64el) + ;; + *) + echo 2>&1 "Error: unknown MIPS target: $mycpu" + exit 1 + esac + ;; *arm*|*armv6l* ) mycpu="arm" ;; *aarch64* ) diff --git a/tools/niminst/makefile.tmpl b/tools/niminst/makefile.tmpl index c4e0be55e..2203d05e9 100644 --- a/tools/niminst/makefile.tmpl +++ b/tools/niminst/makefile.tmpl @@ -114,8 +114,11 @@ endif ifeq ($(ucpu),ppc) mycpu = ppc endif -ifeq ($(ucpu),mips) - mycpu = mips +ifneq (,$(filter $(ucpu), mips mips64)) + mycpu = $(shell /bin/sh -c '"$(CC)" -dumpmachine | sed "s/-.*//"') + ifeq (,$(filter $(mycpu), mips mipsel mips64 mips64el)) + $(error unknown MIPS target: $(mycpu)) + endif endif ifeq ($(ucpu),arm) mycpu = arm -- cgit 1.4.1-2-gfad0 From 6b3af6a5d7a370784c3191c7640965b3b9e00f59 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 7 Aug 2017 00:31:37 +0200 Subject: WIP: --gc:regions instead of --gc:stack --- compiler/commands.nim | 8 +- compiler/options.nim | 2 +- doc/advopt.txt | 2 +- lib/system.nim | 6 +- lib/system/gc_regions.nim | 378 ++++++++++++++++++++++++++++++++++++ lib/system/gc_stack.nim | 474 ---------------------------------------------- lib/system/mmdisp.nim | 6 +- lib/system/sysstr.nim | 11 +- lib/system/threads.nim | 4 +- 9 files changed, 401 insertions(+), 490 deletions(-) create mode 100644 lib/system/gc_regions.nim delete mode 100644 lib/system/gc_stack.nim (limited to 'lib/system.nim') diff --git a/compiler/commands.nim b/compiler/commands.nim index 22e4b5a2c..e837ee922 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -207,7 +207,7 @@ proc testCompileOptionArg*(switch, arg: string, info: TLineInfo): bool = of "generational": result = gSelectedGC == gcGenerational of "go": result = gSelectedGC == gcGo of "none": result = gSelectedGC == gcNone - of "stack": result = gSelectedGC == gcStack + of "stack", "regions": result = gSelectedGC == gcRegions else: localError(info, errNoneBoehmRefcExpectedButXFound, arg) of "opt": case arg.normalize @@ -429,9 +429,9 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; of "none": gSelectedGC = gcNone defineSymbol("nogc") - of "stack": - gSelectedGC= gcStack - defineSymbol("gcstack") + of "stack", "regions": + gSelectedGC= gcRegions + defineSymbol("gcregions") else: localError(info, errNoneBoehmRefcExpectedButXFound, arg) of "warnings", "w": if processOnOffSwitchOrList({optWarns}, arg, pass, info): listWarnings() diff --git a/compiler/options.nim b/compiler/options.nim index 5c39faf3b..e9193f81e 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -94,7 +94,7 @@ type cmdRun # run the project via TCC backend TStringSeq* = seq[string] TGCMode* = enum # the selected GC - gcNone, gcBoehm, gcGo, gcStack, gcMarkAndSweep, gcRefc, + gcNone, gcBoehm, gcGo, gcRegions, gcMarkAndSweep, gcRefc, gcV2, gcGenerational IdeCmd* = enum diff --git a/doc/advopt.txt b/doc/advopt.txt index b88e5f063..fb6fd719b 100644 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -65,7 +65,7 @@ Advanced options: --skipUserCfg do not read the user's configuration file --skipParentCfg do not read the parent dirs' configuration files --skipProjCfg do not read the project's configuration file - --gc:refc|v2|markAndSweep|boehm|go|none + --gc:refc|v2|markAndSweep|boehm|go|none|regions select the GC to use; default is 'refc' --index:on|off turn index file generation on|off --putenv:key=value set an environment variable diff --git a/lib/system.nim b/lib/system.nim index e6d961a35..9ab941635 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2556,7 +2556,7 @@ const NimStackTrace = compileOption("stacktrace") template coroutinesSupportedPlatform(): bool = when defined(sparc) or defined(ELATE) or compileOption("gc", "v2") or - defined(boehmgc) or defined(gogc) or defined(nogc) or defined(gcStack) or + defined(boehmgc) or defined(gogc) or defined(nogc) or defined(gcRegions) or defined(gcMarkAndSweep): false else: @@ -2757,10 +2757,10 @@ when not defined(JS): #and not defined(nimscript): {.push stack_trace: off, profiler:off.} when hasAlloc: - when not defined(gcStack): + when not defined(gcRegions): proc initGC() {.gcsafe.} when not defined(boehmgc) and not defined(useMalloc) and - not defined(gogc) and not defined(gcStack): + not defined(gogc) and not defined(gcRegions): proc initAllocator() {.inline.} proc initStackBottom() {.inline, compilerproc.} = diff --git a/lib/system/gc_regions.nim b/lib/system/gc_regions.nim new file mode 100644 index 000000000..7469373dc --- /dev/null +++ b/lib/system/gc_regions.nim @@ -0,0 +1,378 @@ +# +# Nim's Runtime Library +# (c) Copyright 2016 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +# "Stack GC" for embedded devices or ultra performance requirements. + +when defined(nimphpext): + proc roundup(x, v: int): int {.inline.} = + result = (x + (v-1)) and not (v-1) + proc emalloc(size: int): pointer {.importc: "_emalloc".} + proc efree(mem: pointer) {.importc: "_efree".} + + proc osAllocPages(size: int): pointer {.inline.} = + emalloc(size) + + proc osTryAllocPages(size: int): pointer {.inline.} = + emalloc(size) + + proc osDeallocPages(p: pointer, size: int) {.inline.} = + efree(p) + +else: + include osalloc + +# We manage memory as a thread local stack. Since the allocation pointer +# is detached from the control flow pointer, this model is vastly more +# useful than the traditional programming model while almost as safe. +# Individual objects can also be deleted but no coalescing is performed. +# Stacks can also be moved from one thread to another. + +# We also support 'finalizers'. + +type + Finalizer {.compilerproc.} = proc (self: pointer) {.nimcall, benign.} + # A ref type can have a finalizer that is called before the object's + # storage is freed. + + AlignType = BiggestFloat + ObjHeader = object + typ: PNimType + nextFinal: ptr ObjHeader # next object with finalizer + + Chunk = ptr BaseChunk + BaseChunk = object + next: Chunk + size: int + head, tail: ptr ObjHeader # first and last object in chunk that + # has a finalizer attached to it + +const + MaxSmallObject = 128 + +type + FreeEntry = ptr object + next: FreeEntry + SizedFreeEntry = ptr object + next: SizedFreeEntry + size: int + StackPtr = object + bump: pointer + remaining: int + current: Chunk + + MemRegion* = object + remaining: int + bump: pointer + head, tail: Chunk + nextChunkSize, totalSize: int + freeLists: array[MaxSmallObject div MemAlign, FreeEntry] + holes: SizedFreeEntry + when hasThreadSupport: + lock: SysLock + + SeqHeader = object # minor hack ahead: Since we know that seqs + # and strings cannot have finalizers, we use the field + # instead for a 'region' field so that they can grow + # and shrink safely. + typ: PNimType + region: ptr MemRegion + +var + tlRegion {.threadVar.}: MemRegion +# tempStrRegion {.threadVar.}: MemRegion # not yet used + +template withRegion*(r: MemRegion; body: untyped) = + let oldRegion = tlRegion + tlRegion = r + try: + body + finally: + #r = tlRegion + tlRegion = oldRegion + +template inc(p: pointer, s: int) = + p = cast[pointer](cast[int](p) +% s) + +template dec(p: pointer, s: int) = + p = cast[pointer](cast[int](p) -% s) + +template `+!`(p: pointer, s: int): pointer = + cast[pointer](cast[int](p) +% s) + +template `-!`(p: pointer, s: int): pointer = + cast[pointer](cast[int](p) -% s) + +proc allocSlowPath(r: var MemRegion; size: int) = + # we need to ensure that the underlying linked list + # stays small. Say we want to grab 16GB of RAM with some + # exponential growth function. So we allocate 16KB, then + # 32 KB, 64 KB, 128KB, 256KB, 512KB, 1MB, 2MB, 4MB, + # 8MB, 16MB, 32MB, 64MB, 128MB, 512MB, 1GB, 2GB, 4GB, 8GB, + # 16GB --> list contains only 20 elements! That's reasonable. + if (r.totalSize and 1) == 0: + r.nextChunkSize = + if r.totalSize < 64 * 1024: PageSize*4 + else: r.nextChunkSize*2 + var s = roundup(size+sizeof(BaseChunk), PageSize) + var fresh: Chunk + if s > r.nextChunkSize: + fresh = cast[Chunk](osAllocPages(s)) + else: + fresh = cast[Chunk](osTryAllocPages(r.nextChunkSize)) + if fresh == nil: + fresh = cast[Chunk](osAllocPages(s)) + # lowest bit in totalSize is the "don't increase nextChunkSize" + inc r.totalSize + else: + s = r.nextChunkSize + fresh.size = s + fresh.head = nil + fresh.tail = nil + fresh.next = nil + inc r.totalSize, s + let old = r.tail + if old == nil: + r.head = fresh + else: + r.tail.next = fresh + r.bump = fresh +! sizeof(BaseChunk) + r.tail = fresh + r.remaining = s - sizeof(BaseChunk) + +proc alloc(r: var MemRegion; size: int): pointer = + if size <= MaxSmallObject: + var it = r.freeLists[size div MemAlign] + if it != nil: + r.freeLists[size div MemAlign] = it.next + return pointer(it) + else: + var it = r.holes + var prev: SizedFreeEntry = nil + while it != nil: + if it.size >= size: + if prev != nil: prev.next = it.next + else: r.holes = it.next + return pointer(it) + prev = it + it = it.next + if size > r.remaining: + allocSlowPath(r, size) + sysAssert(size <= r.remaining, "size <= r.remaining") + dec(r.remaining, size) + result = r.bump + inc r.bump, size + +proc runFinalizers(c: Chunk) = + var it = c.head + while it != nil: + # indivually freed objects with finalizer stay in the list, but + # their typ is nil then: + if it.typ != nil and it.typ.finalizer != nil: + (cast[Finalizer](it.typ.finalizer))(it+!sizeof(ObjHeader)) + it = it.nextFinal + +proc dealloc(r: var MemRegion; p: pointer; size: int) = + let it = cast[ptr ObjHeader](p-!sizeof(ObjHeader)) + if it.typ != nil and it.typ.finalizer != nil: + (cast[Finalizer](it.typ.finalizer))(p) + it.typ = nil + # it is benefitial to not use the free lists here: + if r.bump -! size == p: + dec r.bump, size + elif size <= MaxSmallObject: + let it = cast[FreeEntry](p) + it.next = r.freeLists[size div MemAlign] + r.freeLists[size div MemAlign] = it + else: + let it = cast[SizedFreeEntry](p) + it.size = size + it.next = r.holes + r.holes = it + +proc deallocAll(r: var MemRegion; head: Chunk) = + var it = head + while it != nil: + let nxt = it.next + runFinalizers(it) + dec r.totalSize, it.size + osDeallocPages(it, it.size) + it = nxt + +proc deallocAll*(r: var MemRegion) = + deallocAll(r, r.head) + zeroMem(addr r, sizeof r) + +proc obstackPtr*(r: MemRegion): StackPtr = + result.bump = r.bump + result.remaining = r.remaining + result.current = r.tail + +template computeRemaining(r): untyped = + r.tail.size -% (cast[int](r.bump) -% cast[int](r.tail)) + +proc setObstackPtr*(r: var MemRegion; sp: StackPtr) = + # free everything after 'sp': + if sp.current != nil: + deallocAll(r, sp.current.next) + sp.current.next = nil + else: + deallocAll(r, r.head) + r.head = nil + r.bump = sp.bump + r.tail = sp.current + r.remaining = sp.remaining + +proc obstackPtr*(): StackPtr = tlRegion.obstackPtr() +proc setObstackPtr*(sp: StackPtr) = tlRegion.setObstackPtr(sp) +proc deallocAll*() = tlRegion.deallocAll() + +proc deallocOsPages(r: var MemRegion) = r.deallocAll() + +proc joinRegion*(dest: var MemRegion; src: MemRegion) = + # merging is not hard. + if dest.head.isNil: + dest.head = src.head + else: + dest.tail.next = src.head + dest.tail = src.tail + dest.bump = src.bump + dest.remaining = src.remaining + dest.nextChunkSize = max(dest.nextChunkSize, src.nextChunkSize) + inc dest.totalSize, src.totalSize + +proc isOnHeap*(r: MemRegion; p: pointer): bool = + # the tail chunk is the largest, so check it first. It's also special + # in that contains the current bump pointer: + if r.tail >= p and p < r.bump: + return true + var it = r.head + while it != r.tail: + if it >= p and p <= it+!it.size: return true + it = it.next + +proc rawNewObj(r: var MemRegion, typ: PNimType, size: int): pointer = + var res = cast[ptr ObjHeader](alloc(r, size + sizeof(ObjHeader))) + res.typ = typ + if typ.finalizer != nil: + res.nextFinal = r.head.head + r.head.head = res + result = res +! sizeof(ObjHeader) + +proc rawNewSeq(r: var MemRegion, typ: PNimType, size: int): pointer = + var res = cast[ptr SeqHeader](alloc(r, size + sizeof(SeqHeader))) + res.typ = typ + res.region = addr(r) + result = res +! sizeof(SeqHeader) + +proc newObj(typ: PNimType, size: int): pointer {.compilerRtl.} = + result = rawNewObj(tlRegion, typ, size) + zeroMem(result, size) + when defined(memProfiler): nimProfile(size) + +proc newObjNoInit(typ: PNimType, size: int): pointer {.compilerRtl.} = + result = rawNewObj(tlRegion, typ, size) + when defined(memProfiler): nimProfile(size) + +proc newSeq(typ: PNimType, len: int): pointer {.compilerRtl.} = + let size = roundup(addInt(mulInt(len, typ.base.size), GenericSeqSize), + MemAlign) + result = rawNewSeq(tlRegion, typ, size) + zeroMem(result, size) + cast[PGenericSeq](result).len = len + cast[PGenericSeq](result).reserved = len + +proc newStr(typ: PNimType, len: int; init: bool): pointer {.compilerRtl.} = + let size = roundup(addInt(len, GenericSeqSize), MemAlign) + result = rawNewSeq(tlRegion, typ, size) + if init: zeroMem(result, size) + cast[PGenericSeq](result).len = len + cast[PGenericSeq](result).reserved = len + +proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} = + result = rawNewObj(tlRegion, typ, size) + zeroMem(result, size) + +proc newSeqRC1(typ: PNimType, len: int): pointer {.compilerRtl.} = + result = newSeq(typ, len) + +proc growObj(regionUnused: var MemRegion; old: pointer, newsize: int): pointer = + let sh = cast[ptr SeqHeader](old -! sizeof(SeqHeader)) + let typ = sh.typ + result = rawNewSeq(sh.region[], typ, + roundup(newsize, MemAlign)) + let elemSize = if typ.kind == tyString: 1 else: typ.base.size + let oldsize = cast[PGenericSeq](old).len*elemSize + GenericSeqSize + copyMem(result, old, oldsize) + zeroMem(result +! oldsize, newsize-oldsize) + #dealloc(sh.region[], old, roundup(oldsize, MemAlign)) + +proc growObj(old: pointer, newsize: int): pointer {.rtl.} = + result = growObj(tlRegion, old, newsize) + +proc unsureAsgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} = + dest[] = src +proc asgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} = + dest[] = src +proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerproc, inline.} = + dest[] = src + +proc alloc(size: Natural): pointer = + result = c_malloc(size) + if result == nil: raiseOutOfMem() +proc alloc0(size: Natural): pointer = + result = alloc(size) + zeroMem(result, size) +proc realloc(p: pointer, newsize: Natural): pointer = + result = c_realloc(p, newsize) + if result == nil: raiseOutOfMem() +proc dealloc(p: pointer) = c_free(p) + +proc alloc0(r: var MemRegion; size: Natural): pointer = + # ignore the region. That is correct for the channels module + # but incorrect in general. XXX + result = alloc0(size) + +proc dealloc(r: var MemRegion; p: pointer) = dealloc(p) + +proc allocShared(size: Natural): pointer = + result = c_malloc(size) + if result == nil: raiseOutOfMem() +proc allocShared0(size: Natural): pointer = + result = alloc(size) + zeroMem(result, size) +proc reallocShared(p: pointer, newsize: Natural): pointer = + result = c_realloc(p, newsize) + if result == nil: raiseOutOfMem() +proc deallocShared(p: pointer) = c_free(p) + +when hasThreadSupport: + proc getFreeSharedMem(): int = 0 + proc getTotalSharedMem(): int = 0 + proc getOccupiedSharedMem(): int = 0 + +proc GC_disable() = discard +proc GC_enable() = discard +proc GC_fullCollect() = discard +proc GC_setStrategy(strategy: GC_Strategy) = discard +proc GC_enableMarkAndSweep() = discard +proc GC_disableMarkAndSweep() = discard +proc GC_getStatistics(): string = return "" + +proc getOccupiedMem(): int = + result = tlRegion.totalSize - tlRegion.remaining +proc getFreeMem(): int = tlRegion.remaining +proc getTotalMem(): int = + result = tlRegion.totalSize + +proc getOccupiedMem*(r: MemRegion): int = + result = r.totalSize - r.remaining +proc getFreeMem*(r: MemRegion): int = r.remaining +proc getTotalMem*(r: MemRegion): int = + result = r.totalSize + +proc setStackBottom(theStackBottom: pointer) = discard diff --git a/lib/system/gc_stack.nim b/lib/system/gc_stack.nim deleted file mode 100644 index e7b9f65a7..000000000 --- a/lib/system/gc_stack.nim +++ /dev/null @@ -1,474 +0,0 @@ -# -# Nim's Runtime Library -# (c) Copyright 2016 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -# "Stack GC" for embedded devices or ultra performance requirements. - -when defined(nimphpext): - proc roundup(x, v: int): int {.inline.} = - result = (x + (v-1)) and not (v-1) - proc emalloc(size: int): pointer {.importc: "_emalloc".} - proc efree(mem: pointer) {.importc: "_efree".} - - proc osAllocPages(size: int): pointer {.inline.} = - emalloc(size) - - proc osTryAllocPages(size: int): pointer {.inline.} = - emalloc(size) - - proc osDeallocPages(p: pointer, size: int) {.inline.} = - efree(p) - -else: - include osalloc - -# We manage memory as a thread local stack. Since the allocation pointer -# is detached from the control flow pointer, this model is vastly more -# useful than the traditional programming model while almost as safe. -# Individual objects can also be deleted but no coalescing is performed. -# Stacks can also be moved from one thread to another. - -# We also support 'finalizers'. - -type - Finalizer {.compilerproc.} = proc (self: pointer) {.nimcall, benign.} - # A ref type can have a finalizer that is called before the object's - # storage is freed. - - AlignType = BiggestFloat - ObjHeader = object - typ: PNimType - nextFinal: ptr ObjHeader # next object with finalizer - - Hole = object # stacks can have holes. Otherwise 'growObj' would be insane. - zeroTyp: pointer # overlaid with 'typ' field. Always 'nil'. - size: int # size of the free slot - - Chunk = ptr BaseChunk - BaseChunk = object - next: Chunk - size: int - head, tail: ptr ObjHeader # first and last object in chunk that - # has a finalizer attached to it - -type - StackPtr = object - bump: pointer - remaining: int - current: Chunk - - MemRegion* = object - remaining: int - bump: pointer - head, tail: Chunk - nextChunkSize, totalSize: int - hole: ptr Hole # we support individual freeing - when hasThreadSupport: - lock: SysLock - -var - tlRegion {.threadVar.}: MemRegion - -template withRegion*(r: MemRegion; body: untyped) = - let oldRegion = tlRegion - tlRegion = r - try: - body - finally: - #r = tlRegion - tlRegion = oldRegion - -template inc(p: pointer, s: int) = - p = cast[pointer](cast[int](p) +% s) - -template `+!`(p: pointer, s: int): pointer = - cast[pointer](cast[int](p) +% s) - -template `-!`(p: pointer, s: int): pointer = - cast[pointer](cast[int](p) -% s) - -proc allocSlowPath(r: var MemRegion; size: int) = - # we need to ensure that the underlying linked list - # stays small. Say we want to grab 16GB of RAM with some - # exponential growth function. So we allocate 16KB, then - # 32 KB, 64 KB, 128KB, 256KB, 512KB, 1MB, 2MB, 4MB, - # 8MB, 16MB, 32MB, 64MB, 128MB, 512MB, 1GB, 2GB, 4GB, 8GB, - # 16GB --> list contains only 20 elements! That's reasonable. - if (r.totalSize and 1) == 0: - r.nextChunkSize = - if r.totalSize < 64 * 1024: PageSize*4 - else: r.nextChunkSize*2 - var s = roundup(size+sizeof(BaseChunk), PageSize) - var fresh: Chunk - if s > r.nextChunkSize: - fresh = cast[Chunk](osAllocPages(s)) - else: - fresh = cast[Chunk](osTryAllocPages(r.nextChunkSize)) - if fresh == nil: - fresh = cast[Chunk](osAllocPages(s)) - # lowest bit in totalSize is the "don't increase nextChunkSize" - inc r.totalSize - else: - s = r.nextChunkSize - fresh.size = s - fresh.head = nil - fresh.tail = nil - fresh.next = nil - inc r.totalSize, s - let old = r.tail - if old == nil: - r.head = fresh - else: - r.tail.next = fresh - r.bump = fresh +! sizeof(BaseChunk) - r.tail = fresh - r.remaining = s - sizeof(BaseChunk) - -proc alloc(r: var MemRegion; size: int): pointer {.inline.} = - if size > r.remaining: - allocSlowPath(r, size) - sysAssert(size <= r.remaining, "size <= r.remaining") - dec(r.remaining, size) - result = r.bump - inc r.bump, size - -proc runFinalizers(c: Chunk) = - var it = c.head - while it != nil: - # indivually freed objects with finalizer stay in the list, but - # their typ is nil then: - if it.typ != nil and it.typ.finalizer != nil: - (cast[Finalizer](it.typ.finalizer))(it+!sizeof(ObjHeader)) - it = it.nextFinal - -when false: - proc dealloc(r: var MemRegion; p: pointer) = - let it = cast[ptr ObjHeader](p-!sizeof(ObjHeader)) - if it.typ != nil and it.typ.finalizer != nil: - (cast[Finalizer](it.typ.finalizer))(p) - it.typ = nil - -proc deallocAll(r: var MemRegion; head: Chunk) = - var it = head - while it != nil: - let nxt = it.next - runFinalizers(it) - dec r.totalSize, it.size - osDeallocPages(it, it.size) - it = nxt - -proc deallocAll*(r: var MemRegion) = - deallocAll(r, r.head) - zeroMem(addr r, sizeof r) - -proc obstackPtr*(r: MemRegion): StackPtr = - result.bump = r.bump - result.remaining = r.remaining - result.current = r.tail - -template computeRemaining(r): untyped = - r.tail.size -% (cast[int](r.bump) -% cast[int](r.tail)) - -proc setObstackPtr*(r: var MemRegion; sp: StackPtr) = - # free everything after 'sp': - if sp.current != nil: - deallocAll(r, sp.current.next) - sp.current.next = nil - else: - deallocAll(r, r.head) - r.head = nil - r.bump = sp.bump - r.tail = sp.current - r.remaining = sp.remaining - -proc obstackPtr*(): StackPtr = tlRegion.obstackPtr() -proc setObstackPtr*(sp: StackPtr) = tlRegion.setObstackPtr(sp) -proc deallocAll*() = tlRegion.deallocAll() - -proc deallocOsPages(r: var MemRegion) = r.deallocAll() - -proc joinRegion*(dest: var MemRegion; src: MemRegion) = - # merging is not hard. - if dest.head.isNil: - dest.head = src.head - else: - dest.tail.next = src.head - dest.tail = src.tail - dest.bump = src.bump - dest.remaining = src.remaining - dest.nextChunkSize = max(dest.nextChunkSize, src.nextChunkSize) - inc dest.totalSize, src.totalSize - -proc isOnHeap*(r: MemRegion; p: pointer): bool = - # the tail chunk is the largest, so check it first. It's also special - # in that contains the current bump pointer: - if r.tail >= p and p < r.bump: - return true - var it = r.head - while it != r.tail: - if it >= p and p <= it+!it.size: return true - it = it.next - -when false: - # essential feature for later: copy data over from one region to another - - proc isInteriorPointer(r: MemRegion; p: pointer): pointer = - discard " we cannot patch stack pointers anyway!" - - type - PointerStackChunk = object - next, prev: ptr PointerStackChunk - len: int - data: array[128, pointer] - - template head(s: PointerStackChunk): untyped = s.prev - template tail(s: PointerStackChunk): untyped = s.next - - include chains - - proc push(r: var MemRegion; s: var PointerStackChunk; x: pointer) = - if s.len < high(s.data): - s.data[s.len] = x - inc s.len - else: - let fresh = cast[ptr PointerStackChunk](alloc(r, sizeof(PointerStackChunk))) - fresh.len = 1 - fresh.data[0] = x - fresh.next = nil - fresh.prev = nil - append(s, fresh) - - - proc genericDeepCopyAux(dr: var MemRegion; stack: var PointerStackChunk; - dest, src: pointer, mt: PNimType) {.benign.} - proc genericDeepCopyAux(dr: var MemRegion; stack: var PointerStackChunk; - dest, src: pointer, n: ptr TNimNode) {.benign.} = - var - d = cast[ByteAddress](dest) - s = cast[ByteAddress](src) - case n.kind - of nkSlot: - genericDeepCopyAux(cast[pointer](d +% n.offset), - cast[pointer](s +% n.offset), n.typ) - of nkList: - for i in 0..n.len-1: - genericDeepCopyAux(dest, src, n.sons[i]) - of nkCase: - var dd = selectBranch(dest, n) - var m = selectBranch(src, n) - # reset if different branches are in use; note different branches also - # imply that's not self-assignment (``x = x``)! - if m != dd and dd != nil: - genericResetAux(dest, dd) - copyMem(cast[pointer](d +% n.offset), cast[pointer](s +% n.offset), - n.typ.size) - if m != nil: - genericDeepCopyAux(dest, src, m) - of nkNone: sysAssert(false, "genericDeepCopyAux") - - proc copyDeepString(dr: var MemRegion; stack: var PointerStackChunk; src: NimString): NimString {.inline.} = - result = rawNewStringNoInit(dr, src.len) - result.len = src.len - copyMem(result.data, src.data, src.len + 1) - - proc genericDeepCopyAux(dr: var MemRegion; stack: var PointerStackChunk; - dest, src: pointer, mt: PNimType) = - var - d = cast[ByteAddress](dest) - s = cast[ByteAddress](src) - sysAssert(mt != nil, "genericDeepCopyAux 2") - case mt.kind - of tyString: - var x = cast[PPointer](dest) - var s2 = cast[PPointer](s)[] - if s2 == nil: - x[] = nil - else: - x[] = copyDeepString(cast[NimString](s2)) - of tySequence: - var s2 = cast[PPointer](src)[] - var seq = cast[PGenericSeq](s2) - var x = cast[PPointer](dest) - if s2 == nil: - x[] = nil - return - sysAssert(dest != nil, "genericDeepCopyAux 3") - x[] = newSeq(mt, seq.len) - var dst = cast[ByteAddress](cast[PPointer](dest)[]) - for i in 0..seq.len-1: - genericDeepCopyAux(dr, stack, - cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize), - cast[pointer](cast[ByteAddress](s2) +% i *% mt.base.size +% - GenericSeqSize), - mt.base) - of tyObject: - # we need to copy m_type field for tyObject, as it could be empty for - # sequence reallocations: - var pint = cast[ptr PNimType](dest) - pint[] = cast[ptr PNimType](src)[] - if mt.base != nil: - genericDeepCopyAux(dr, stack, dest, src, mt.base) - genericDeepCopyAux(dr, stack, dest, src, mt.node) - of tyTuple: - genericDeepCopyAux(dr, stack, dest, src, mt.node) - of tyArray, tyArrayConstr: - for i in 0..(mt.size div mt.base.size)-1: - genericDeepCopyAux(dr, stack, - cast[pointer](d +% i*% mt.base.size), - cast[pointer](s +% i*% mt.base.size), mt.base) - of tyRef: - let s2 = cast[PPointer](src)[] - if s2 == nil: - cast[PPointer](dest)[] = nil - else: - # we modify the header of the cell temporarily; instead of the type - # field we store a forwarding pointer. XXX This is bad when the cloning - # fails due to OOM etc. - let x = usrToCell(s2) - let forw = cast[int](x.typ) - if (forw and 1) == 1: - # we stored a forwarding pointer, so let's use that: - let z = cast[pointer](forw and not 1) - unsureAsgnRef(cast[PPointer](dest), z) - else: - let realType = x.typ - let z = newObj(realType, realType.base.size) - - unsureAsgnRef(cast[PPointer](dest), z) - x.typ = cast[PNimType](cast[int](z) or 1) - genericDeepCopyAux(dr, stack, z, s2, realType.base) - x.typ = realType - else: - copyMem(dest, src, mt.size) - - proc joinAliveDataFromRegion*(dest: var MemRegion; src: var MemRegion; - root: pointer): pointer = - # we mark the alive data and copy only alive data over to 'dest'. - # This is O(liveset) but it nicely compacts memory, so it's fine. - # We use the 'typ' field as a forwarding pointer. The forwarding - # pointers have bit 0 set, so we can disambiguate them. - # We allocate a temporary stack in 'src' that we later free: - var s: PointerStackChunk - s.len = 1 - s.data[0] = root - while s.len > 0: - var p: pointer - if s.tail == nil: - p = s.data[s.len-1] - dec s.len - else: - p = s.tail.data[s.tail.len-1] - dec s.tail.len - if s.tail.len == 0: - unlink(s, s.tail) - -proc rawNewObj(r: var MemRegion, typ: PNimType, size: int): pointer = - var res = cast[ptr ObjHeader](alloc(r, size + sizeof(ObjHeader))) - res.typ = typ - if typ.finalizer != nil: - res.nextFinal = r.head.head - r.head.head = res - result = res +! sizeof(ObjHeader) - -proc newObj(typ: PNimType, size: int): pointer {.compilerRtl.} = - result = rawNewObj(tlRegion, typ, size) - zeroMem(result, size) - when defined(memProfiler): nimProfile(size) - -proc newObjNoInit(typ: PNimType, size: int): pointer {.compilerRtl.} = - result = rawNewObj(tlRegion, typ, size) - when defined(memProfiler): nimProfile(size) - -proc newSeq(typ: PNimType, len: int): pointer {.compilerRtl.} = - let size = addInt(mulInt(len, typ.base.size), GenericSeqSize) - result = newObj(typ, size) - cast[PGenericSeq](result).len = len - cast[PGenericSeq](result).reserved = len - -proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} = - result = rawNewObj(tlRegion, typ, size) - zeroMem(result, size) - -proc newSeqRC1(typ: PNimType, len: int): pointer {.compilerRtl.} = - let size = addInt(mulInt(len, typ.base.size), GenericSeqSize) - result = newObj(typ, size) - cast[PGenericSeq](result).len = len - cast[PGenericSeq](result).reserved = len - -proc growObj(region: var MemRegion; old: pointer, newsize: int): pointer = - let typ = cast[ptr ObjHeader](old -! sizeof(ObjHeader)).typ - result = rawNewObj(region, typ, newsize) - let elemSize = if typ.kind == tyString: 1 else: typ.base.size - let oldsize = cast[PGenericSeq](old).len*elemSize + GenericSeqSize - copyMem(result, old, oldsize) - zeroMem(result +! oldsize, newsize-oldsize) - -proc growObj(old: pointer, newsize: int): pointer {.rtl.} = - result = growObj(tlRegion, old, newsize) - -proc unsureAsgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} = - dest[] = src -proc asgnRef(dest: PPointer, src: pointer) {.compilerproc, inline.} = - dest[] = src -proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerproc, inline.} = - dest[] = src - -proc alloc(size: Natural): pointer = - result = c_malloc(size) - if result == nil: raiseOutOfMem() -proc alloc0(size: Natural): pointer = - result = alloc(size) - zeroMem(result, size) -proc realloc(p: pointer, newsize: Natural): pointer = - result = c_realloc(p, newsize) - if result == nil: raiseOutOfMem() -proc dealloc(p: pointer) = c_free(p) - -proc alloc0(r: var MemRegion; size: Natural): pointer = - # ignore the region. That is correct for the channels module - # but incorrect in general. XXX - result = alloc0(size) - -proc dealloc(r: var MemRegion; p: pointer) = dealloc(p) - -proc allocShared(size: Natural): pointer = - result = c_malloc(size) - if result == nil: raiseOutOfMem() -proc allocShared0(size: Natural): pointer = - result = alloc(size) - zeroMem(result, size) -proc reallocShared(p: pointer, newsize: Natural): pointer = - result = c_realloc(p, newsize) - if result == nil: raiseOutOfMem() -proc deallocShared(p: pointer) = c_free(p) - -when hasThreadSupport: - proc getFreeSharedMem(): int = 0 - proc getTotalSharedMem(): int = 0 - proc getOccupiedSharedMem(): int = 0 - -proc GC_disable() = discard -proc GC_enable() = discard -proc GC_fullCollect() = discard -proc GC_setStrategy(strategy: GC_Strategy) = discard -proc GC_enableMarkAndSweep() = discard -proc GC_disableMarkAndSweep() = discard -proc GC_getStatistics(): string = return "" - -proc getOccupiedMem(): int = - result = tlRegion.totalSize - tlRegion.remaining -proc getFreeMem(): int = tlRegion.remaining -proc getTotalMem(): int = - result = tlRegion.totalSize - -proc getOccupiedMem*(r: MemRegion): int = - result = r.totalSize - r.remaining -proc getFreeMem*(r: MemRegion): int = r.remaining -proc getTotalMem*(r: MemRegion): int = - result = r.totalSize - -proc setStackBottom(theStackBottom: pointer) = discard diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim index 35fa0ce9a..fb2f3471f 100644 --- a/lib/system/mmdisp.nim +++ b/lib/system/mmdisp.nim @@ -543,7 +543,7 @@ elif defined(nogc): include "system/cellsets" else: - when not defined(gcStack): + when not defined(gcRegions): include "system/alloc" include "system/cellsets" @@ -551,9 +551,9 @@ else: sysAssert(sizeof(Cell) == sizeof(FreeCell), "sizeof FreeCell") when compileOption("gc", "v2"): include "system/gc2" - elif defined(gcStack): + elif defined(gcRegions): # XXX due to bootstrapping reasons, we cannot use compileOption("gc", "stack") here - include "system/gc_stack" + include "system/gc_regions" elif defined(gcMarkAndSweep): # XXX use 'compileOption' here include "system/gc_ms" diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim index d3d3d5a95..c3150cb07 100644 --- a/lib/system/sysstr.nim +++ b/lib/system/sysstr.nim @@ -38,6 +38,13 @@ when declared(allocAtomic): template allocStrNoInit(size: untyped): untyped = cast[NimString](boehmAllocAtomic(size)) +elif defined(gcRegions): + template allocStr(size: untyped): untyped = + cast[NimString](newStr(addr(strDesc), size, true)) + + template allocStrNoInit(size: untyped): untyped = + cast[NimString](newStr(addr(strDesc), size, false)) + else: template allocStr(size: untyped): untyped = cast[NimString](newObj(addr(strDesc), size)) @@ -99,7 +106,7 @@ proc copyString(src: NimString): NimString {.compilerRtl.} = proc copyStringRC1(src: NimString): NimString {.compilerRtl.} = if src != nil: - when declared(newObjRC1): + when declared(newObjRC1) and not defined(gcRegions): var s = src.len if s < 7: s = 7 result = cast[NimString](newObjRC1(addr(strDesc), sizeof(TGenericSeq) + @@ -235,7 +242,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {. # we need to decref here, otherwise the GC leaks! when not defined(boehmGC) and not defined(nogc) and not defined(gcMarkAndSweep) and not defined(gogc) and - not defined(gcStack): + not defined(gcRegions): when false: # compileOption("gc", "v2"): for i in newLen..result.len-1: let len0 = gch.tempStack.len diff --git a/lib/system/threads.nim b/lib/system/threads.nim index 754d07181..a7a811844 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -396,7 +396,7 @@ template afterThreadRuns() = for i in countdown(threadDestructionHandlers.len-1, 0): threadDestructionHandlers[i]() -when not defined(boehmgc) and not hasSharedHeap and not defined(gogc) and not defined(gcstack): +when not defined(boehmgc) and not hasSharedHeap and not defined(gogc) and not defined(gcRegions): proc deallocOsPages() when defined(boehmgc): @@ -434,7 +434,7 @@ else: proc threadProcWrapStackFrame[TArg](thrd: ptr Thread[TArg]) = when defined(boehmgc): boehmGC_call_with_stack_base(threadProcWrapDispatch[TArg], thrd) - elif not defined(nogc) and not defined(gogc) and not defined(gcstack): + elif not defined(nogc) and not defined(gogc) and not defined(gcRegions): var p {.volatile.}: proc(a: ptr Thread[TArg]) {.nimcall.} = threadProcWrapDispatch[TArg] when not hasSharedHeap: -- cgit 1.4.1-2-gfad0 From 43cac7f174a8a48af681443eb98a3047892c96c4 Mon Sep 17 00:00:00 2001 From: "Lynn C. Rees" Date: Sat, 19 Aug 2017 00:48:03 -0600 Subject: Use of deprecated object name (#6256) --- lib/system.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/system.nim') diff --git a/lib/system.nim b/lib/system.nim index 9ab941635..42d2ff0b1 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -422,7 +422,7 @@ type RootEffect* {.compilerproc.} = object of RootObj ## \ ## base effect class; each effect should - ## inherit from `TEffect` unless you know what + ## inherit from `RootEffect` unless you know what ## you doing. TimeEffect* = object of RootEffect ## Time effect. IOEffect* = object of RootEffect ## IO effect. -- cgit 1.4.1-2-gfad0 From 22684370b0eb5938bc7a4172dc968e4c557a02ee Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Mon, 28 Aug 2017 21:44:35 +0800 Subject: remove ArrayDummySize with unchecked arrays (#5818) --- doc/manual/ffi.txt | 6 +----- lib/pure/collections/rtarrays.nim | 2 +- lib/pure/collections/sharedstrings.nim | 4 +--- lib/pure/ioselectors.nim | 2 +- lib/system.nim | 14 +++++++------- lib/system/cellsets.nim | 5 ++--- lib/system/mmdisp.nim | 2 +- lib/system/sysio.nim | 8 ++++---- lib/system/widestrs.nim | 2 +- tests/array/tunchecked.nim | 5 +++++ tests/metatype/ttypedesc2.nim | 3 +-- 11 files changed, 25 insertions(+), 28 deletions(-) create mode 100644 tests/array/tunchecked.nim (limited to 'lib/system.nim') diff --git a/doc/manual/ffi.txt b/doc/manual/ffi.txt index e9b52eaca..06fed1430 100644 --- a/doc/manual/ffi.txt +++ b/doc/manual/ffi.txt @@ -132,7 +132,7 @@ translated into a C array of undetermined size: .. code-block:: nim type - ArrayPart{.unchecked.} = array[0..0, int] + ArrayPart{.unchecked.} = array[0, int] MySeq = object len, cap: int data: ArrayPart @@ -146,10 +146,6 @@ Produces roughly this C code: NI data[]; } MySeq; -The bounds checking done at compile time is not disabled for now, so to access -``s.data[C]`` (where ``C`` is a constant) the array's index needs to -include ``C``. - The base type of the unchecked array may not contain any GC'ed memory but this is currently not checked. diff --git a/lib/pure/collections/rtarrays.nim b/lib/pure/collections/rtarrays.nim index 89a02553a..3849117a0 100644 --- a/lib/pure/collections/rtarrays.nim +++ b/lib/pure/collections/rtarrays.nim @@ -19,7 +19,7 @@ type L: Natural spart: seq[T] apart: array[ArrayPartSize, T] - UncheckedArray* {.unchecked.}[T] = array[0..100_000_000, T] + UncheckedArray* {.unchecked.}[T] = array[0, T] template usesSeqPart(x): untyped = x.L > ArrayPartSize diff --git a/lib/pure/collections/sharedstrings.nim b/lib/pure/collections/sharedstrings.nim index 10ab30767..a9e194fb4 100644 --- a/lib/pure/collections/sharedstrings.nim +++ b/lib/pure/collections/sharedstrings.nim @@ -9,10 +9,8 @@ ## Shared string support for Nim. -const ArrayDummySize = when defined(cpu16): 10_000 else: 100_000_000 - type - UncheckedCharArray {.unchecked.} = array[0..ArrayDummySize, char] + UncheckedCharArray = UncheckedArray[char] type Buffer = ptr object diff --git a/lib/pure/ioselectors.nim b/lib/pure/ioselectors.nim index cbef5ce0d..ef8072221 100644 --- a/lib/pure/ioselectors.nim +++ b/lib/pure/ioselectors.nim @@ -208,7 +208,7 @@ else: import locks type - SharedArray {.unchecked.}[T] = array[0..100, T] + SharedArray[T] = UncheckedArray[T] proc allocSharedArray[T](nsize: int): ptr SharedArray[T] = result = cast[ptr SharedArray[T]](allocShared0(sizeof(T) * nsize)) diff --git a/lib/system.nim b/lib/system.nim index 42d2ff0b1..419fa3c94 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -268,6 +268,9 @@ type seq*{.magic: "Seq".}[T] ## Generic type to construct sequences. set*{.magic: "Set".}[T] ## Generic type to construct bit sets. + UncheckedArray* {.unchecked.}[T] = array[0, T] + ## Array with no boudns checking + when defined(nimArrIdx): # :array|openarray|string|seq|cstring|tuple proc `[]`*[I: Ordinal;T](a: T; i: I): T {. @@ -381,8 +384,6 @@ include "system/inclrtl" const NoFakeVars* = defined(nimscript) ## true if the backend doesn't support \ ## "fake variables" like 'var EBADF {.importc.}: cint'. -const ArrayDummySize = when defined(cpu16): 10_000 else: 100_000_000 - when not defined(JS): type TGenericSeq {.compilerproc, pure, inheritable.} = object @@ -390,10 +391,9 @@ when not defined(JS): when defined(gogc): elemSize: int PGenericSeq {.exportc.} = ptr TGenericSeq - UncheckedCharArray {.unchecked.} = array[0..ArrayDummySize, char] # len and space without counting the terminating zero: NimStringDesc {.compilerproc, final.} = object of TGenericSeq - data: UncheckedCharArray + data: UncheckedArray[char] NimString = ptr NimStringDesc when not defined(JS) and not defined(nimscript): @@ -1600,8 +1600,7 @@ type # these work for most platforms: culonglong* {.importc: "unsigned long long", nodecl.} = uint64 ## This is the same as the type ``unsigned long long`` in *C*. - cstringArray* {.importc: "char**", nodecl.} = ptr - array[0..ArrayDummySize, cstring] + cstringArray* {.importc: "char**", nodecl.} = ptr UncheckedArray[cstring] ## This is binary compatible to the type ``char**`` in *C*. The array's ## high value is large enough to disable bounds checking in practice. ## Use `cstringArrayToSeq` to convert it into a ``seq[string]``. @@ -3045,7 +3044,8 @@ when not defined(JS): #and not defined(nimscript): ## creates a NULL terminated cstringArray from `a`. The result has to ## be freed with `deallocCStringArray` after it's not needed anymore. result = cast[cstringArray](alloc0((a.len+1) * sizeof(cstring))) - let x = cast[ptr array[0..ArrayDummySize, string]](a) + + let x = cast[ptr UncheckedArray[string]](a) for i in 0 .. a.high: result[i] = cast[cstring](alloc0(x[i].len+1)) copyMem(result[i], addr(x[i][0]), x[i].len) diff --git a/lib/system/cellsets.nim b/lib/system/cellsets.nim index ab6191aab..f26cb86ab 100644 --- a/lib/system/cellsets.nim +++ b/lib/system/cellsets.nim @@ -30,13 +30,12 @@ type key: ByteAddress # start address at bit 0 bits: array[BitIndex, int] # a bit vector - PPageDescArray = ptr array[ArrayDummySize, PPageDesc] + PPageDescArray = ptr UncheckedArray[PPageDesc] CellSet {.final, pure.} = object counter, max: int head: PPageDesc data: PPageDescArray - - PCellArray = ptr array[ArrayDummySize, PCell] + PCellArray = ptr UncheckedArray[PCell] CellSeq {.final, pure.} = object len, cap: int d: PCellArray diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim index fb2f3471f..d2160fdac 100644 --- a/lib/system/mmdisp.nim +++ b/lib/system/mmdisp.nim @@ -34,7 +34,7 @@ const type PPointer = ptr pointer - ByteArray = array[0..ArrayDummySize, byte] + ByteArray = UncheckedArray[byte] PByte = ptr ByteArray PString = ptr string {.deprecated: [TByteArray: ByteArray].} diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim index c9049a134..7b6d93fe0 100644 --- a/lib/system/sysio.nim +++ b/lib/system/sysio.nim @@ -86,11 +86,11 @@ proc writeBuffer(f: File, buffer: pointer, len: Natural): int = checkErr(f) proc writeBytes(f: File, a: openArray[int8|uint8], start, len: Natural): int = - var x = cast[ptr array[ArrayDummySize, int8]](a) - result = writeBuffer(f, addr(x[start]), len) + var x = cast[ptr UncheckedArray[int8]](a) + result = writeBuffer(f, addr(x[int(start)]), len) proc writeChars(f: File, a: openArray[char], start, len: Natural): int = - var x = cast[ptr array[ArrayDummySize, int8]](a) - result = writeBuffer(f, addr(x[start]), len) + var x = cast[ptr UncheckedArray[int8]](a) + result = writeBuffer(f, addr(x[int(start)]), len) proc write(f: File, s: string) = if writeBuffer(f, cstring(s), s.len) != s.len: diff --git a/lib/system/widestrs.nim b/lib/system/widestrs.nim index d11ed7d1b..a8b28c279 100644 --- a/lib/system/widestrs.nim +++ b/lib/system/widestrs.nim @@ -15,7 +15,7 @@ when not declared(NimString): type Utf16Char* = distinct int16 - WideCString* = ref array[ArrayDummySize, Utf16Char] + WideCString* = ref UncheckedArray[Utf16Char] {.deprecated: [TUtf16Char: Utf16Char].} proc len*(w: WideCString): int = diff --git a/tests/array/tunchecked.nim b/tests/array/tunchecked.nim new file mode 100644 index 000000000..f5ac3642d --- /dev/null +++ b/tests/array/tunchecked.nim @@ -0,0 +1,5 @@ +{.boundchecks: on.} +type Unchecked {.unchecked.} = array[0, char] + +var x = cast[ptr Unchecked](alloc(100)) +x[5] = 'x' diff --git a/tests/metatype/ttypedesc2.nim b/tests/metatype/ttypedesc2.nim index e576ec91a..7650a6f6b 100644 --- a/tests/metatype/ttypedesc2.nim +++ b/tests/metatype/ttypedesc2.nim @@ -18,11 +18,10 @@ when true: uoffset_t* = uint32 FlatBufferBuilder* = object - uarray* {.unchecked.} [T] = array [0..0, T] Array* [T] = object o*: uoffset_t len*: int - data*: ptr uarray[T] + data*: ptr UncheckedArray[T] proc ca* (fbb: ptr FlatBufferBuilder, T: typedesc, len: int): Array[T] {.noinit.} = result.len = len -- cgit 1.4.1-2-gfad0 From a3f82a574f4f9a795b53c96b989f0aa7cec09295 Mon Sep 17 00:00:00 2001 From: Daniil Yarancev <21169548+Yardanico@users.noreply.github.com> Date: Mon, 28 Aug 2017 19:14:11 +0300 Subject: Fix typo (#6285) --- lib/system.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/system.nim') diff --git a/lib/system.nim b/lib/system.nim index 419fa3c94..51967c7ea 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -269,7 +269,7 @@ type set*{.magic: "Set".}[T] ## Generic type to construct bit sets. UncheckedArray* {.unchecked.}[T] = array[0, T] - ## Array with no boudns checking + ## Array with no bounds checking when defined(nimArrIdx): # :array|openarray|string|seq|cstring|tuple -- cgit 1.4.1-2-gfad0 From eb8371012c359e387a7c73b97ef333c783086641 Mon Sep 17 00:00:00 2001 From: Daniil Yarancev <21169548+Yardanico@users.noreply.github.com> Date: Tue, 29 Aug 2017 16:46:22 +0300 Subject: Fix #6288 (#6289 was created for wrong branch) (#6291) --- lib/system.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/system.nim') diff --git a/lib/system.nim b/lib/system.nim index 51967c7ea..93152a9e0 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -3757,7 +3757,7 @@ when hasAlloc: proc locals*(): RootObj {.magic: "Plugin", noSideEffect.} = ## generates a tuple constructor expression listing all the local variables ## in the current scope. This is quite fast as it does not rely - ## on any debug or runtime information. Note that in constrast to what + ## on any debug or runtime information. Note that in contrast to what ## the official signature says, the return type is not ``RootObj`` but a ## tuple of a structure that depends on the current scope. Example: ## -- cgit 1.4.1-2-gfad0 From 8d714d2b02458553234869d7139afb73621f6d7d Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Wed, 30 Aug 2017 23:14:33 +0200 Subject: low/high/of are now overloadable operations --- compiler/semexprs.nim | 41 +++-------------------------------------- compiler/semmagic.nim | 36 ++++++++++++++++++++++++++++++++++++ lib/system.nim | 43 +++++++++++++++++++++++++------------------ 3 files changed, 64 insertions(+), 56 deletions(-) (limited to 'lib/system.nim') diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 81799e762..63039b36d 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -274,41 +274,6 @@ proc semSizeof(c: PContext, n: PNode): PNode = n.typ = getSysType(tyInt) result = n -proc semOf(c: PContext, n: PNode): PNode = - if sonsLen(n) == 3: - n.sons[1] = semExprWithType(c, n.sons[1]) - n.sons[2] = semExprWithType(c, n.sons[2], {efDetermineType}) - #restoreOldStyleType(n.sons[1]) - #restoreOldStyleType(n.sons[2]) - let a = skipTypes(n.sons[1].typ, abstractPtrs) - let b = skipTypes(n.sons[2].typ, abstractPtrs) - let x = skipTypes(n.sons[1].typ, abstractPtrs-{tyTypeDesc}) - let y = skipTypes(n.sons[2].typ, abstractPtrs-{tyTypeDesc}) - - if x.kind == tyTypeDesc or y.kind != tyTypeDesc: - localError(n.info, errXExpectsObjectTypes, "of") - elif b.kind != tyObject or a.kind != tyObject: - localError(n.info, errXExpectsObjectTypes, "of") - else: - let diff = inheritanceDiff(a, b) - # | returns: 0 iff `a` == `b` - # | returns: -x iff `a` is the x'th direct superclass of `b` - # | returns: +x iff `a` is the x'th direct subclass of `b` - # | returns: `maxint` iff `a` and `b` are not compatible at all - if diff <= 0: - # optimize to true: - message(n.info, hintConditionAlwaysTrue, renderTree(n)) - result = newIntNode(nkIntLit, 1) - result.info = n.info - result.typ = getSysType(tyBool) - return result - elif diff == high(int): - localError(n.info, errXcanNeverBeOfThisSubtype, typeToString(a)) - else: - localError(n.info, errXExpectsTwoArguments, "of") - n.typ = getSysType(tyBool) - result = n - proc isOpImpl(c: PContext, n: PNode, flags: TExprFlags): PNode = internalAssert n.sonsLen == 3 and n[1].typ != nil and n[1].typ.kind == tyTypeDesc and @@ -1831,11 +1796,11 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = of mDefined: result = semDefined(c, setMs(n, s), false) of mDefinedInScope: result = semDefined(c, setMs(n, s), true) of mCompiles: result = semCompiles(c, setMs(n, s), flags) - of mLow: result = semLowHigh(c, setMs(n, s), mLow) - of mHigh: result = semLowHigh(c, setMs(n, s), mHigh) + #of mLow: result = semLowHigh(c, setMs(n, s), mLow) + #of mHigh: result = semLowHigh(c, setMs(n, s), mHigh) of mSizeOf: result = semSizeof(c, setMs(n, s)) of mIs: result = semIs(c, setMs(n, s), flags) - of mOf: result = semOf(c, setMs(n, s)) + #of mOf: result = semOf(c, setMs(n, s)) of mShallowCopy: result = semShallowCopy(c, n, flags) of mExpandToAst: result = semExpandToAst(c, n, s, flags) of mQuoteAst: result = semQuoteAst(c, n) diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index c664f735c..8b3d9c014 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -200,6 +200,41 @@ proc isStrangeArray(t: PType): bool = let t = t.skipTypes(abstractInst) result = t.kind == tyArray and t.firstOrd != 0 +proc semOf(c: PContext, n: PNode): PNode = + if sonsLen(n) == 3: + n.sons[1] = semExprWithType(c, n.sons[1]) + n.sons[2] = semExprWithType(c, n.sons[2], {efDetermineType}) + #restoreOldStyleType(n.sons[1]) + #restoreOldStyleType(n.sons[2]) + let a = skipTypes(n.sons[1].typ, abstractPtrs) + let b = skipTypes(n.sons[2].typ, abstractPtrs) + let x = skipTypes(n.sons[1].typ, abstractPtrs-{tyTypeDesc}) + let y = skipTypes(n.sons[2].typ, abstractPtrs-{tyTypeDesc}) + + if x.kind == tyTypeDesc or y.kind != tyTypeDesc: + localError(n.info, errXExpectsObjectTypes, "of") + elif b.kind != tyObject or a.kind != tyObject: + localError(n.info, errXExpectsObjectTypes, "of") + else: + let diff = inheritanceDiff(a, b) + # | returns: 0 iff `a` == `b` + # | returns: -x iff `a` is the x'th direct superclass of `b` + # | returns: +x iff `a` is the x'th direct subclass of `b` + # | returns: `maxint` iff `a` and `b` are not compatible at all + if diff <= 0: + # optimize to true: + message(n.info, hintConditionAlwaysTrue, renderTree(n)) + result = newIntNode(nkIntLit, 1) + result.info = n.info + result.typ = getSysType(tyBool) + return result + elif diff == high(int): + localError(n.info, errXcanNeverBeOfThisSubtype, typeToString(a)) + else: + localError(n.info, errXExpectsTwoArguments, "of") + n.typ = getSysType(tyBool) + result = n + proc magicsAfterOverloadResolution(c: PContext, n: PNode, flags: TExprFlags): PNode = case n[0].sym.magic @@ -219,6 +254,7 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, result.typ = getSysType(tyString) of mInstantiationInfo: result = semInstantiationInfo(c, n) of mOrd: result = semOrd(c, n) + of mOf: result = semOf(c, n) of mHigh, mLow: result = semLowHigh(c, n, n[0].sym.magic) of mShallowCopy: result = semShallowCopy(c, n, flags) of mNBindSym: result = semBindSym(c, n) diff --git a/lib/system.nim b/lib/system.nim index 93152a9e0..f8896ed13 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -231,9 +231,22 @@ proc reset*[T](obj: var T) {.magic: "Reset", noSideEffect.} ## resets an object `obj` to its initial (binary zero) value. This needs to ## be called before any possible `object branch transition`:idx:. -# for low and high the return type T may not be correct, but -# we handle that with compiler magic in semLowHigh() -proc high*[T](x: T): T {.magic: "High", noSideEffect.} +type + range*{.magic: "Range".}[T] ## Generic type to construct range types. + array*{.magic: "Array".}[I, T] ## Generic type to construct + ## fixed-length arrays. + openArray*{.magic: "OpenArray".}[T] ## Generic type to construct open arrays. + ## Open arrays are implemented as a + ## pointer to the array data and a + ## length field. + varargs*{.magic: "Varargs".}[T] ## Generic type to construct a varargs type. + seq*{.magic: "Seq".}[T] ## Generic type to construct sequences. + set*{.magic: "Set".}[T] ## Generic type to construct bit sets. + + UncheckedArray* {.unchecked.}[T] = array[0, T] + ## Array with no bounds checking + +proc high*[T: Ordinal](x: T): T {.magic: "High", noSideEffect.} ## returns the highest possible index of an array, a sequence, a string or ## the highest possible value of an ordinal value `x`. As a special ## semantic rule, `x` may also be a type identifier. @@ -245,6 +258,13 @@ proc high*[T](x: T): T {.magic: "High", noSideEffect.} ## high(2) #=> 9223372036854775807 ## high(int) #=> 9223372036854775807 +proc high*[T: Ordinal](x: typeDesc[T]): T {.magic: "High", noSideEffect.} +proc high*[T](x: openArray[T]): int {.magic: "High", noSideEffect.} +proc high*[I, T](x: array[I, T]): I {.magic: "High", noSideEffect.} + +proc low*[T: Ordinal](x: typeDesc[T]): T {.magic: "Low", noSideEffect.} +proc low*[T](x: openArray[T]): int {.magic: "Low", noSideEffect.} +proc low*[I, T](x: array[I, T]): I {.magic: "Low", noSideEffect.} proc low*[T](x: T): T {.magic: "Low", noSideEffect.} ## returns the lowest possible index of an array, a sequence, a string or ## the lowest possible value of an ordinal value `x`. As a special @@ -256,21 +276,6 @@ proc low*[T](x: T): T {.magic: "Low", noSideEffect.} ## low(2) #=> -9223372036854775808 ## low(int) #=> -9223372036854775808 -type - range*{.magic: "Range".}[T] ## Generic type to construct range types. - array*{.magic: "Array".}[I, T] ## Generic type to construct - ## fixed-length arrays. - openArray*{.magic: "OpenArray".}[T] ## Generic type to construct open arrays. - ## Open arrays are implemented as a - ## pointer to the array data and a - ## length field. - varargs*{.magic: "Varargs".}[T] ## Generic type to construct a varargs type. - seq*{.magic: "Seq".}[T] ## Generic type to construct sequences. - set*{.magic: "Set".}[T] ## Generic type to construct bit sets. - - UncheckedArray* {.unchecked.}[T] = array[0, T] - ## Array with no bounds checking - when defined(nimArrIdx): # :array|openarray|string|seq|cstring|tuple proc `[]`*[I: Ordinal;T](a: T; i: I): T {. @@ -1175,6 +1180,8 @@ proc `is` *[T, S](x: T, y: S): bool {.magic: "Is", noSideEffect.} template `isnot` *(x, y: untyped): untyped = not (x is y) ## Negated version of `is`. Equivalent to ``not(x is y)``. +proc `of` *[T, S](x: typeDesc[T], y: typeDesc[S]): bool {.magic: "Of", noSideEffect.} +proc `of` *[T, S](x: T, y: typeDesc[S]): bool {.magic: "Of", noSideEffect.} proc `of` *[T, S](x: T, y: S): bool {.magic: "Of", noSideEffect.} ## Checks if `x` has a type of `y` ## -- cgit 1.4.1-2-gfad0 From a08fb61da974e7384d63fd2e08f60c97594a01c6 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Thu, 31 Aug 2017 13:59:25 +0200 Subject: make tests green again --- compiler/semexprs.nim | 6 ++++-- lib/system.nim | 8 +++++++- tests/concepts/t3330.nim | 8 ++++---- 3 files changed, 15 insertions(+), 7 deletions(-) (limited to 'lib/system.nim') diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 63039b36d..65557658a 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1085,9 +1085,11 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = if ty.n != nil and ty.n.kind == nkRecList: let field = lookupInRecord(ty.n, i) if field != nil: - n.typ = newTypeWithSons(c, tyFieldAccessor, @[ty, field.typ]) - n.typ.n = copyTree(n) + n.typ = makeTypeDesc(c, field.typ) return n + #n.typ = newTypeWithSons(c, tyFieldAccessor, @[ty, field.typ]) + #n.typ.n = copyTree(n) + #return n else: tryReadingGenericParam(ty) return diff --git a/lib/system.nim b/lib/system.nim index f8896ed13..9efa850ed 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -261,12 +261,18 @@ proc high*[T: Ordinal](x: T): T {.magic: "High", noSideEffect.} proc high*[T: Ordinal](x: typeDesc[T]): T {.magic: "High", noSideEffect.} proc high*[T](x: openArray[T]): int {.magic: "High", noSideEffect.} proc high*[I, T](x: array[I, T]): I {.magic: "High", noSideEffect.} +proc high*[I, T](x: typeDesc[array[I, T]]): I {.magic: "High", noSideEffect.} +proc high*(x: cstring): int {.magic: "High", noSideEffect.} +proc high*(x: string): int {.magic: "High", noSideEffect.} proc low*[T: Ordinal](x: typeDesc[T]): T {.magic: "Low", noSideEffect.} proc low*[T](x: openArray[T]): int {.magic: "Low", noSideEffect.} proc low*[I, T](x: array[I, T]): I {.magic: "Low", noSideEffect.} proc low*[T](x: T): T {.magic: "Low", noSideEffect.} - ## returns the lowest possible index of an array, a sequence, a string or +proc low*[I, T](x: typeDesc[array[I, T]]): I {.magic: "Low", noSideEffect.} +proc low*(x: cstring): int {.magic: "Low", noSideEffect.} +proc low*(x: string): int {.magic: "Low", noSideEffect.} +## returns the lowest possible index of an array, a sequence, a string or ## the lowest possible value of an ordinal value `x`. As a special ## semantic rule, `x` may also be a type identifier. ## diff --git a/tests/concepts/t3330.nim b/tests/concepts/t3330.nim index 04add2b6f..fcd5054ef 100644 --- a/tests/concepts/t3330.nim +++ b/tests/concepts/t3330.nim @@ -2,16 +2,16 @@ discard """ errormsg: "type mismatch: got (Bar[system.int])" nimout: ''' t3330.nim(40, 4) Error: type mismatch: got (Bar[system.int]) -but expected one of: +but expected one of: proc test(foo: Foo[int]) t3330.nim(25, 8) Hint: Non-matching candidates for add(k, string, T) -proc add[T](x: var seq[T]; y: T) -proc add(result: var string; x: float) proc add(x: var string; y: string) -proc add(x: var string; y: cstring) proc add(x: var string; y: char) proc add(result: var string; x: int64) +proc add(x: var string; y: cstring) +proc add(result: var string; x: float) proc add[T](x: var seq[T]; y: openArray[T]) +proc add[T](x: var seq[T]; y: T) t3330.nim(25, 8) template/generic instantiation from here t3330.nim(32, 6) Foo: 'bar.value' cannot be assigned to -- cgit 1.4.1-2-gfad0