doc updates; fixes 'inc' for 'char'

This commit is contained in:
Araq 2015-03-29 13:16:22 +02:00
commit edc4940c26
8 changed files with 97 additions and 191 deletions

View file

@ -492,7 +492,7 @@ proc binaryArithOverflowRaw(p: BProc, t: PType, a, b: TLoc;
else: getTypeDesc(p.module, t) else: getTypeDesc(p.module, t)
result = getTempName() result = getTempName()
linefmt(p, cpsLocals, "$1 $2;$n", storage, result) linefmt(p, cpsLocals, "$1 $2;$n", storage, result)
lineCg(p, cpsStmts, frmt, result, rdLoc(a), rdLoc(b)) lineCg(p, cpsStmts, frmt, result, rdCharLoc(a), rdCharLoc(b))
if size < platform.intSize or t.kind in {tyRange, tyEnum}: if size < platform.intSize or t.kind in {tyRange, tyEnum}:
linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseOverflow();$n", linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseOverflow();$n",
result, intLiteral(firstOrd(t)), intLiteral(lastOrd(t))) result, intLiteral(firstOrd(t)), intLiteral(lastOrd(t)))

View file

@ -9,7 +9,7 @@
import import
os, lists, strutils, strtabs, osproc, sets os, lists, strutils, strtabs, osproc, sets
const const
hasTinyCBackend* = defined(tinyc) hasTinyCBackend* = defined(tinyc)
useEffectSystem* = true useEffectSystem* = true
@ -21,10 +21,10 @@ const
type # please make sure we have under 32 options type # please make sure we have under 32 options
# (improves code efficiency a lot!) # (improves code efficiency a lot!)
TOption* = enum # **keep binary compatible** TOption* = enum # **keep binary compatible**
optNone, optObjCheck, optFieldCheck, optRangeCheck, optBoundsCheck, optNone, optObjCheck, optFieldCheck, optRangeCheck, optBoundsCheck,
optOverflowCheck, optNilCheck, optOverflowCheck, optNilCheck,
optNaNCheck, optInfCheck, optNaNCheck, optInfCheck,
optAssert, optLineDir, optWarns, optHints, optAssert, optLineDir, optWarns, optHints,
optOptimizeSpeed, optOptimizeSize, optStackTrace, # stack tracing support optOptimizeSpeed, optOptimizeSize, optStackTrace, # stack tracing support
optLineTrace, # line tracing support (includes stack tracing) optLineTrace, # line tracing support (includes stack tracing)
optEndb, # embedded debugger optEndb, # embedded debugger
@ -37,8 +37,8 @@ type # please make sure we have under 32 options
TOptions* = set[TOption] TOptions* = set[TOption]
TGlobalOption* = enum # **keep binary compatible** TGlobalOption* = enum # **keep binary compatible**
gloptNone, optForceFullMake, optDeadCodeElim, gloptNone, optForceFullMake, optDeadCodeElim,
optListCmd, optCompileOnly, optNoLinking, optListCmd, optCompileOnly, optNoLinking,
optSafeCode, # only allow safe code optSafeCode, # only allow safe code
optCDebug, # turn on debugging information optCDebug, # turn on debugging information
optGenDynLib, # generate a dynamic library optGenDynLib, # generate a dynamic library
@ -67,9 +67,9 @@ type # please make sure we have under 32 options
TGlobalOptions* = set[TGlobalOption] TGlobalOptions* = set[TGlobalOption]
TCommands* = enum # Nim's commands TCommands* = enum # Nim's commands
# **keep binary compatible** # **keep binary compatible**
cmdNone, cmdCompileToC, cmdCompileToCpp, cmdCompileToOC, cmdNone, cmdCompileToC, cmdCompileToCpp, cmdCompileToOC,
cmdCompileToJS, cmdCompileToLLVM, cmdInterpret, cmdPretty, cmdDoc, cmdCompileToJS, cmdCompileToLLVM, cmdInterpret, cmdPretty, cmdDoc,
cmdGenDepend, cmdDump, cmdGenDepend, cmdDump,
cmdCheck, # semantic checking for whole project cmdCheck, # semantic checking for whole project
cmdParse, # parse a single file (for debugging) cmdParse, # parse a single file (for debugging)
cmdScan, # scan a single file (for debugging) cmdScan, # scan a single file (for debugging)
@ -90,12 +90,12 @@ var
gIdeCmd*: TIdeCmd gIdeCmd*: TIdeCmd
const const
ChecksOptions* = {optObjCheck, optFieldCheck, optRangeCheck, optNilCheck, ChecksOptions* = {optObjCheck, optFieldCheck, optRangeCheck, optNilCheck,
optOverflowCheck, optBoundsCheck, optAssert, optNaNCheck, optInfCheck} optOverflowCheck, optBoundsCheck, optAssert, optNaNCheck, optInfCheck}
var var
gOptions*: TOptions = {optObjCheck, optFieldCheck, optRangeCheck, gOptions*: TOptions = {optObjCheck, optFieldCheck, optRangeCheck,
optBoundsCheck, optOverflowCheck, optAssert, optWarns, optBoundsCheck, optOverflowCheck, optAssert, optWarns,
optHints, optStackTrace, optLineTrace, optHints, optStackTrace, optLineTrace,
optPatterns, optNilCheck} optPatterns, optNilCheck}
gGlobalOptions*: TGlobalOptions = {optThreadAnalysis} gGlobalOptions*: TGlobalOptions = {optThreadAnalysis}
@ -129,7 +129,7 @@ template optPreserveOrigSource*: expr =
template optPrintSurroundingSrc*: expr = template optPrintSurroundingSrc*: expr =
gVerbosity >= 2 gVerbosity >= 2
const const
genSubDir* = "nimcache" genSubDir* = "nimcache"
NimExt* = "nim" NimExt* = "nim"
RodExt* = "rod" RodExt* = "rod"
@ -168,20 +168,20 @@ proc mainCommandArg*: string =
else: else:
result = gProjectName result = gProjectName
proc existsConfigVar*(key: string): bool = proc existsConfigVar*(key: string): bool =
result = hasKey(gConfigVars, key) result = hasKey(gConfigVars, key)
proc getConfigVar*(key: string): string = proc getConfigVar*(key: string): string =
result = gConfigVars[key] result = gConfigVars[key]
proc setConfigVar*(key, val: string) = proc setConfigVar*(key, val: string) =
gConfigVars[key] = val gConfigVars[key] = val
proc getOutFile*(filename, ext: string): string = proc getOutFile*(filename, ext: string): string =
if options.outFile != "": result = options.outFile if options.outFile != "": result = options.outFile
else: result = changeFileExt(filename, ext) else: result = changeFileExt(filename, ext)
proc getPrefixDir*(): string = proc getPrefixDir*(): string =
## gets the application directory ## gets the application directory
result = splitPath(getAppDir()).head result = splitPath(getAppDir()).head
@ -189,22 +189,22 @@ proc canonicalizePath*(path: string): string =
when not FileSystemCaseSensitive: result = path.expandFilename.toLower when not FileSystemCaseSensitive: result = path.expandFilename.toLower
else: result = path.expandFilename else: result = path.expandFilename
proc shortenDir*(dir: string): string = proc shortenDir*(dir: string): string =
## returns the interesting part of a dir ## returns the interesting part of a dir
var prefix = getPrefixDir() & DirSep var prefix = getPrefixDir() & DirSep
if startsWith(dir, prefix): if startsWith(dir, prefix):
return substr(dir, len(prefix)) return substr(dir, len(prefix))
prefix = gProjectPath & DirSep prefix = gProjectPath & DirSep
if startsWith(dir, prefix): if startsWith(dir, prefix):
return substr(dir, len(prefix)) return substr(dir, len(prefix))
result = dir result = dir
proc removeTrailingDirSep*(path: string): string = proc removeTrailingDirSep*(path: string): string =
if (len(path) > 0) and (path[len(path) - 1] == DirSep): if (len(path) > 0) and (path[len(path) - 1] == DirSep):
result = substr(path, 0, len(path) - 2) result = substr(path, 0, len(path) - 2)
else: else:
result = path result = path
proc getGeneratedPath: string = proc getGeneratedPath: string =
result = if nimcacheDir.len > 0: nimcacheDir else: gProjectPath.shortenDir / result = if nimcacheDir.len > 0: nimcacheDir else: gProjectPath.shortenDir /
genSubDir genSubDir
@ -257,7 +257,7 @@ proc withPackageName*(path: string): string =
let (p, file, ext) = path.splitFile let (p, file, ext) = path.splitFile
result = (p / (x & '_' & file)) & ext result = (p / (x & '_' & file)) & ext
proc toGeneratedFile*(path, ext: string): string = proc toGeneratedFile*(path, ext: string): string =
## converts "/home/a/mymodule.nim", "rod" to "/home/a/nimcache/mymodule.rod" ## converts "/home/a/mymodule.nim", "rod" to "/home/a/nimcache/mymodule.rod"
var (head, tail) = splitPath(path) var (head, tail) = splitPath(path)
#if len(head) > 0: head = shortenDir(head & dirSep) #if len(head) > 0: head = shortenDir(head & dirSep)
@ -301,7 +301,7 @@ proc completeGeneratedFilePath*(f: string, createSubDir: bool = true): string =
result = joinPath(subdir, tail) result = joinPath(subdir, tail)
#echo "completeGeneratedFilePath(", f, ") = ", result #echo "completeGeneratedFilePath(", f, ") = ", result
iterator iterSearchPath*(searchPaths: TLinkedList): string = iterator iterSearchPath*(searchPaths: TLinkedList): string =
var it = PStrEntry(searchPaths.head) var it = PStrEntry(searchPaths.head)
while it != nil: while it != nil:
yield it.data yield it.data
@ -324,7 +324,7 @@ proc rawFindFile2(f: string): string =
it = PStrEntry(it.next) it = PStrEntry(it.next)
result = "" result = ""
proc findFile*(f: string): string {.procvar.} = proc findFile*(f: string): string {.procvar.} =
result = f.rawFindFile result = f.rawFindFile
if result.len == 0: if result.len == 0:
result = f.toLower.rawFindFile result = f.toLower.rawFindFile
@ -351,7 +351,7 @@ proc findModule*(modulename, currentModule: string): string =
if not existsFile(result): if not existsFile(result):
result = findFile(m) result = findFile(m)
proc libCandidates*(s: string, dest: var seq[string]) = proc libCandidates*(s: string, dest: var seq[string]) =
var le = strutils.find(s, '(') var le = strutils.find(s, '(')
var ri = strutils.find(s, ')', le+1) var ri = strutils.find(s, ')', le+1)
if le >= 0 and ri > le: if le >= 0 and ri > le:
@ -359,7 +359,7 @@ proc libCandidates*(s: string, dest: var seq[string]) =
var suffix = substr(s, ri + 1) var suffix = substr(s, ri + 1)
for middle in split(substr(s, le + 1, ri - 1), '|'): for middle in split(substr(s, le + 1, ri - 1), '|'):
libCandidates(prefix & middle & suffix, dest) libCandidates(prefix & middle & suffix, dest)
else: else:
add(dest, s) add(dest, s)
proc canonDynlibName(s: string): string = proc canonDynlibName(s: string): string =
@ -376,17 +376,17 @@ proc inclDynlibOverride*(lib: string) =
proc isDynlibOverride*(lib: string): bool = proc isDynlibOverride*(lib: string): bool =
result = gDllOverrides.hasKey(lib.canonDynlibName) result = gDllOverrides.hasKey(lib.canonDynlibName)
proc binaryStrSearch*(x: openArray[string], y: string): int = proc binaryStrSearch*(x: openArray[string], y: string): int =
var a = 0 var a = 0
var b = len(x) - 1 var b = len(x) - 1
while a <= b: while a <= b:
var mid = (a + b) div 2 var mid = (a + b) div 2
var c = cmpIgnoreCase(x[mid], y) var c = cmpIgnoreCase(x[mid], y)
if c < 0: if c < 0:
a = mid + 1 a = mid + 1
elif c > 0: elif c > 0:
b = mid - 1 b = mid - 1
else: else:
return mid return mid
result = - 1 result = - 1

View file

@ -14,7 +14,7 @@ deprecated pragma
The deprecated pragma is used to mark a symbol as deprecated: The deprecated pragma is used to mark a symbol as deprecated:
.. code-block:: nimrod .. code-block:: nim
proc p() {.deprecated.} proc p() {.deprecated.}
var x {.deprecated.}: char var x {.deprecated.}: char
@ -22,7 +22,7 @@ It can also be used as a statement. Then it takes a list of *renamings*. The
upcoming ``nimfix`` tool can automatically update the code and perform these upcoming ``nimfix`` tool can automatically update the code and perform these
renamings: renamings:
.. code-block:: nimrod .. code-block:: nim
type type
File = object File = object
Stream = ref object Stream = ref object
@ -78,7 +78,7 @@ as helpers for macros.
noReturn pragma noReturn pragma
--------------- ---------------
The ``noreturn`` pragma is used to mark a proc that never returns. The ``noreturn`` pragma is used to mark a proc that never returns.
acyclic pragma acyclic pragma
@ -122,25 +122,25 @@ shallow pragma
-------------- --------------
The ``shallow`` pragma affects the semantics of a type: The compiler is The ``shallow`` pragma affects the semantics of a type: The compiler is
allowed to make a shallow copy. This can cause serious semantic issues and allowed to make a shallow copy. This can cause serious semantic issues and
break memory safety! However, it can speed up assignments considerably, break memory safety! However, it can speed up assignments considerably,
because the semantics of Nim require deep copying of sequences and strings. because the semantics of Nim require deep copying of sequences and strings.
This can be expensive, especially if sequences are used to build a tree This can be expensive, especially if sequences are used to build a tree
structure: structure:
.. code-block:: nim .. code-block:: nim
type type
NodeKind = enum nkLeaf, nkInner NodeKind = enum nkLeaf, nkInner
Node {.final, shallow.} = object Node {.final, shallow.} = object
case kind: NodeKind case kind: NodeKind
of nkLeaf: of nkLeaf:
strVal: string strVal: string
of nkInner: of nkInner:
children: seq[Node] children: seq[Node]
pure pragma pure pragma
----------- -----------
An object type can be marked with the ``pure`` pragma so that its type An object type can be marked with the ``pure`` pragma so that its type
field which is used for runtime type identification is omitted. This used to be field which is used for runtime type identification is omitted. This used to be
necessary for binary compatibility with other compiled languages. necessary for binary compatibility with other compiled languages.
@ -163,12 +163,12 @@ error pragma
------------ ------------
The ``error`` pragma is used to make the compiler output an error message The ``error`` pragma is used to make the compiler output an error message
with the given content. Compilation does not necessarily abort after an error with the given content. Compilation does not necessarily abort after an error
though. though.
The ``error`` pragma can also be used to The ``error`` pragma can also be used to
annotate a symbol (like an iterator or proc). The *usage* of the symbol then annotate a symbol (like an iterator or proc). The *usage* of the symbol then
triggers a compile-time error. This is especially useful to rule out that some triggers a compile-time error. This is especially useful to rule out that some
operation is valid due to overloading and type conversions: operation is valid due to overloading and type conversions:
.. code-block:: nim .. code-block:: nim
## check that underlying int values are compared and not the pointers: ## check that underlying int values are compared and not the pointers:
@ -201,7 +201,7 @@ The ``line`` pragma can be used to affect line information of the annotated
statement as seen in stack backtraces: statement as seen in stack backtraces:
.. code-block:: nim .. code-block:: nim
template myassert*(cond: expr, msg = "") = template myassert*(cond: expr, msg = "") =
if not cond: if not cond:
# change run-time line information of the 'raise' statement: # change run-time line information of the 'raise' statement:
@ -215,26 +215,26 @@ If the ``line`` pragma is used with a parameter, the parameter needs be a
linearScanEnd pragma linearScanEnd pragma
-------------------- --------------------
The ``linearScanEnd`` pragma can be used to tell the compiler how to The ``linearScanEnd`` pragma can be used to tell the compiler how to
compile a Nim `case`:idx: statement. Syntactically it has to be used as a compile a Nim `case`:idx: statement. Syntactically it has to be used as a
statement: statement:
.. code-block:: nim .. code-block:: nim
case myInt case myInt
of 0: of 0:
echo "most common case" echo "most common case"
of 1: of 1:
{.linearScanEnd.} {.linearScanEnd.}
echo "second most common case" echo "second most common case"
of 2: echo "unlikely: use branch table" of 2: echo "unlikely: use branch table"
else: echo "unlikely too: use branch table for ", myInt else: echo "unlikely too: use branch table for ", myInt
In the example, the case branches ``0`` and ``1`` are much more common than In the example, the case branches ``0`` and ``1`` are much more common than
the other cases. Therefore the generated assembler code should test for these the other cases. Therefore the generated assembler code should test for these
values first, so that the CPU's branch predictor has a good chance to succeed values first, so that the CPU's branch predictor has a good chance to succeed
(avoiding an expensive CPU pipeline stall). The other cases might be put into a (avoiding an expensive CPU pipeline stall). The other cases might be put into a
jump table for O(1) overhead, but at the cost of a (very likely) pipeline jump table for O(1) overhead, but at the cost of a (very likely) pipeline
stall. stall.
The ``linearScanEnd`` pragma should be put into the last branch that should be The ``linearScanEnd`` pragma should be put into the last branch that should be
tested against via linear scanning. If put into the last branch of the tested against via linear scanning. If put into the last branch of the
@ -243,8 +243,8 @@ whole ``case`` statement, the whole ``case`` statement uses linear scanning.
computedGoto pragma computedGoto pragma
------------------- -------------------
The ``computedGoto`` pragma can be used to tell the compiler how to The ``computedGoto`` pragma can be used to tell the compiler how to
compile a Nim `case`:idx: in a ``while true`` statement. compile a Nim `case`:idx: in a ``while true`` statement.
Syntactically it has to be used as a statement inside the loop: Syntactically it has to be used as a statement inside the loop:
.. code-block:: nim .. code-block:: nim
@ -278,21 +278,21 @@ Syntactically it has to be used as a statement inside the loop:
of enumE: of enumE:
break break
inc(pc) inc(pc)
vm() vm()
As the example shows ``computedGoto`` is mostly useful for interpreters. If As the example shows ``computedGoto`` is mostly useful for interpreters. If
the underlying backend (C compiler) does not support the computed goto the underlying backend (C compiler) does not support the computed goto
extension the pragma is simply ignored. extension the pragma is simply ignored.
unroll pragma unroll pragma
------------- -------------
The ``unroll`` pragma can be used to tell the compiler that it should unroll The ``unroll`` pragma can be used to tell the compiler that it should unroll
a `for`:idx: or `while`:idx: loop for runtime efficiency: a `for`:idx: or `while`:idx: loop for runtime efficiency:
.. code-block:: nim .. code-block:: nim
proc searchChar(s: string, c: char): int = proc searchChar(s: string, c: char): int =
for i in 0 .. s.high: for i in 0 .. s.high:
{.unroll: 4.} {.unroll: 4.}
if s[i] == c: return i if s[i] == c: return i
@ -440,7 +440,7 @@ Example:
Please note that if a callable symbol is never used in this scenario, its body Please note that if a callable symbol is never used in this scenario, its body
will never be compiled. This is the default behavior leading to best compilation will never be compiled. This is the default behavior leading to best compilation
times, but if exhaustive compilation of all definitions is required, using times, but if exhaustive compilation of all definitions is required, using
``nim check`` provides this option as well. ``nim check`` provides this option as well.
Example: Example:
@ -461,9 +461,9 @@ Example:
pragma pragma pragma pragma
------------- -------------
The ``pragma`` pragma can be used to declare user defined pragmas. This is The ``pragma`` pragma can be used to declare user defined pragmas. This is
useful because Nim's templates and macros do not affect pragmas. User useful because Nim's templates and macros do not affect pragmas. User
defined pragmas are in a different module-wide scope than all other symbols. defined pragmas are in a different module-wide scope than all other symbols.
They cannot be imported from a module. They cannot be imported from a module.
Example: Example:
@ -473,8 +473,8 @@ Example:
{.pragma: rtl, exportc, dynlib, cdecl.} {.pragma: rtl, exportc, dynlib, cdecl.}
else: else:
{.pragma: rtl, importc, dynlib: "client.dll", cdecl.} {.pragma: rtl, importc, dynlib: "client.dll", cdecl.}
proc p*(a, b: int): int {.rtl.} = proc p*(a, b: int): int {.rtl.} =
result = a+b result = a+b
In the example a new pragma named ``rtl`` is introduced that either imports In the example a new pragma named ``rtl`` is introduced that either imports

View file

@ -1,16 +1,16 @@
Threads Threads
======= =======
To enable thread support the ``--threads:on`` command line switch needs to To enable thread support the ``--threads:on`` command line switch needs to
be used. The ``system`` module then contains several threading primitives. be used. The ``system`` module then contains several threading primitives.
See the `threads <threads.html>`_ and `channels <channels.html>`_ modules See the `threads <threads.html>`_ and `channels <channels.html>`_ modules
for the low level thread API. There are also high level parallelism constructs for the low level thread API. There are also high level parallelism constructs
available. See `spawn`_ for further details. available. See `spawn`_ for further details.
Nim's memory model for threads is quite different than that of other common Nim's memory model for threads is quite different than that of other common
programming languages (C, Pascal, Java): Each thread has its own (garbage programming languages (C, Pascal, Java): Each thread has its own (garbage
collected) heap and sharing of memory is restricted to global variables. This collected) heap and sharing of memory is restricted to global variables. This
helps to prevent race conditions. GC efficiency is improved quite a lot, helps to prevent race conditions. GC efficiency is improved quite a lot,
because the GC never has to stop other threads and see what they reference. because the GC never has to stop other threads and see what they reference.
Memory allocation requires no lock at all! This design easily scales to massive Memory allocation requires no lock at all! This design easily scales to massive
multicore processors that are becoming the norm. multicore processors that are becoming the norm.
@ -22,10 +22,10 @@ Thread pragma
A proc that is executed as a new thread of execution should be marked by the A proc that is executed as a new thread of execution should be marked by the
``thread`` pragma for reasons of readability. The compiler checks for ``thread`` pragma for reasons of readability. The compiler checks for
violations of the `no heap sharing restriction`:idx:\: This restriction implies violations of the `no heap sharing restriction`:idx:\: This restriction implies
that it is invalid to construct a data structure that consists of memory that it is invalid to construct a data structure that consists of memory
allocated from different (thread local) heaps. allocated from different (thread local) heaps.
A thread proc is passed to ``createThread`` or ``spawn`` and invoked A thread proc is passed to ``createThread`` or ``spawn`` and invoked
indirectly; so the ``thread`` pragma implies ``procvar``. indirectly; so the ``thread`` pragma implies ``procvar``.
@ -34,7 +34,7 @@ GC safety
We call a proc ``p`` `GC safe`:idx: when it doesn't access any global variable We call a proc ``p`` `GC safe`:idx: when it doesn't access any global variable
that contains GC'ed memory (``string``, ``seq``, ``ref`` or a closure) either that contains GC'ed memory (``string``, ``seq``, ``ref`` or a closure) either
directly or indirectly through a call to a GC unsafe proc. directly or indirectly through a call to a GC unsafe proc.
The `gcsafe`:idx: annotation can be used to mark a proc to be gcsafe, The `gcsafe`:idx: annotation can be used to mark a proc to be gcsafe,
otherwise this property is inferred by the compiler. Note that ``noSideEfect`` otherwise this property is inferred by the compiler. Note that ``noSideEfect``
@ -45,10 +45,9 @@ contain a ``ref`` or ``closure`` type. This enforces
the *no heap sharing restriction*. the *no heap sharing restriction*.
Routines that are imported from C are always assumed to be ``gcsafe``. Routines that are imported from C are always assumed to be ``gcsafe``.
To enable the GC-safety checking the ``--threadAnalysis:on`` command line To disable the GC-safety checking the ``--threadAnalysis:off`` command line
switch must be used. This is a temporary workaround to ease the porting effort switch can be used. This is a temporary workaround to ease the porting effort
from old code to the new threading model. In the future the thread analysis from old code to the new threading model.
will always be performed.
Future directions: Future directions:
@ -59,13 +58,13 @@ Future directions:
Threadvar pragma Threadvar pragma
---------------- ----------------
A global variable can be marked with the ``threadvar`` pragma; it is A global variable can be marked with the ``threadvar`` pragma; it is
a `thread-local`:idx: variable then: a `thread-local`:idx: variable then:
.. code-block:: nim .. code-block:: nim
var checkpoints* {.threadvar.}: seq[string] var checkpoints* {.threadvar.}: seq[string]
Due to implementation restrictions thread local variables cannot be Due to implementation restrictions thread local variables cannot be
initialized within the ``var`` section. (Every thread local variable needs to initialized within the ``var`` section. (Every thread local variable needs to
be replicated at thread creation.) be replicated at thread creation.)
@ -73,7 +72,7 @@ be replicated at thread creation.)
Threads and exceptions Threads and exceptions
---------------------- ----------------------
The interaction between threads and exceptions is simple: A *handled* exception The interaction between threads and exceptions is simple: A *handled* exception
in one thread cannot affect any other thread. However, an *unhandled* exception in one thread cannot affect any other thread. However, an *unhandled* exception
in one thread terminates the whole *process*! in one thread terminates the whole *process*!
@ -82,7 +81,7 @@ in one thread terminates the whole *process*!
Parallel & Spawn Parallel & Spawn
================ ================
Nim has two flavors of parallelism: Nim has two flavors of parallelism:
1) `Structured`:idx: parallelism via the ``parallel`` statement. 1) `Structured`:idx: parallelism via the ``parallel`` statement.
2) `Unstructured`:idx: parallelism via the standalone ``spawn`` statement. 2) `Unstructured`:idx: parallelism via the standalone ``spawn`` statement.
@ -115,7 +114,7 @@ Spawn statement
proc processLine(line: string) = proc processLine(line: string) =
discard "do some heavy lifting here" discard "do some heavy lifting here"
for x in lines("myinput.txt"): for x in lines("myinput.txt"):
spawn processLine(x) spawn processLine(x)
sync() sync()
@ -144,7 +143,7 @@ wait on multiple flow variables at the same time:
.. code-block:: nim .. code-block:: nim
import threadpool, ... import threadpool, ...
# wait until 2 out of 3 servers received the update: # wait until 2 out of 3 servers received the update:
proc main = proc main =
var responses = newSeq[RawFlowVar](3) var responses = newSeq[RawFlowVar](3)
@ -203,8 +202,7 @@ restrictions / changes:
the ``parallel`` section. This is called the *immutability check*. Currently the ``parallel`` section. This is called the *immutability check*. Currently
it is not specified what exactly "complex location" means. We need to make it is not specified what exactly "complex location" means. We need to make
this an optimization! this an optimization!
* Every array access has to be provably within bounds. This is called * Every array access has to be provably within bounds. This is called
the *bounds check*. the *bounds check*.
* Slices are optimized so that no copy is performed. This optimization is not * Slices are optimized so that no copy is performed. This optimization is not
yet performed for ordinary slices outside of a ``parallel`` section. Slices yet performed for ordinary slices outside of a ``parallel`` section.
are also special in that they currently do not support negative indexes!

10
tests/misc/tcharinc.nim Normal file
View file

@ -0,0 +1,10 @@
discard """
output: "1"
"""
var c = '\0'
while true:
if c == '\xFF': break
inc c
echo "1"

View file

@ -1,53 +0,0 @@
discard """
disabled: true
"""
import
gtk2, glib2, atk, gdk2, gdk2pixbuf, libglade2, pango,
pangoutils
proc hello(widget: PWidget, data: pointer) {.cdecl.} =
write(stdout, "Hello World\n")
proc delete_event(widget: PWidget, event: PEvent,
data: pointer): bool {.cdecl.} =
# If you return FALSE in the "delete_event" signal handler,
# GTK will emit the "destroy" signal. Returning TRUE means
# you don't want the window to be destroyed.
# This is useful for popping up 'are you sure you want to quit?'
# type dialogs.
write(stdout, "delete event occurred\n")
# Change TRUE to FALSE and the main window will be destroyed with
# a "delete_event".
return false
# Another callback
proc mydestroy(widget: PWidget, data: pointer) {.cdecl.} =
gtk2.main_quit()
proc mymain() =
# GtkWidget is the storage type for widgets
gtk2.nimrod_init()
var window = window_new(gtk2.WINDOW_TOPLEVEL)
discard g_signal_connect(window, "delete_event",
Gcallback(delete_event), nil)
discard g_signal_connect(window, "destroy", Gcallback(mydestroy), nil)
# Sets the border width of the window.
set_border_width(window, 10)
# Creates a new button with the label "Hello World".
var button = button_new("Hello World")
discard g_signal_connect(button, "clicked", Gcallback(hello), nil)
# This packs the button into the window (a gtk container).
add(window, button)
# The final step is to display this newly created widget.
show(button)
# and the window
show(window)
gtk2.main()
mymain()

View file

@ -1,28 +0,0 @@
discard """
disabled: true
"""
# Test wether the bindings at least compile...
import
unicode, cgi, terminal, libcurl,
parsexml, parseopt, parsecfg,
osproc, complex,
sdl, smpeg, sdl_gfx, sdl_net, sdl_mixer, sdl_ttf,
sdl_image, sdl_mixer_nosmpeg,
cursorfont, xatom, xf86vmode, xkb, xrandr, xshm, xvlib, keysym, xcms, xi,
xkblib, xrender, xutil, x, xf86dga, xinerama, xlib, xresource, xv,
gtk2, glib2, pango, gdk2,
cairowin32, cairoxlib,
odbcsql,
gl, glut, glu, glx, glext, wingl,
lua, lualib, lauxlib, mysql, sqlite3, python, tcl,
db_postgres, db_mysql, db_sqlite, ropes, sockets, browsers, httpserver,
httpclient, parseutils, unidecode, xmldom, xmldomparser, xmltree, xmlparser,
htmlparser, re, graphics, colors, pegs, subexes, dialogs
when defined(linux):
import
zlib, zipfiles
writeln(stdout, "test compilation of binding modules")

View file

@ -1,21 +0,0 @@
discard """
disabled: true
"""
# Test wether the bindings at least compile...
import
tcl,
sdl, smpeg, sdl_gfx, sdl_net, sdl_mixer, sdl_ttf,
sdl_image, sdl_mixer_nosmpeg,
gtk2, glib2, pango, gdk2,
unicode, cgi, terminal, libcurl,
parsexml, parseopt, parsecfg,
osproc,
cairowin32, cairoxlib,
gl, glut, glu, glx, glext, wingl,
lua, lualib, lauxlib, mysql, sqlite3, db_mongo, md5, asyncio, mimetypes,
cookies, events, ftpclient, scgi, irc
writeln(stdout, "test compilation of binding modules")