doc updates; fixes 'inc' for 'char'

This commit is contained in:
Araq
2015-03-29 13:16:22 +02:00
parent 165619552a
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)
result = getTempName()
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}:
linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseOverflow();$n",
result, intLiteral(firstOrd(t)), intLiteral(lastOrd(t)))

View File

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

View File

@@ -14,7 +14,7 @@ deprecated pragma
The deprecated pragma is used to mark a symbol as deprecated:
.. code-block:: nimrod
.. code-block:: nim
proc p() {.deprecated.}
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
renamings:
.. code-block:: nimrod
.. code-block:: nim
type
File = object
Stream = ref object
@@ -78,7 +78,7 @@ as helpers for macros.
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
@@ -122,25 +122,25 @@ shallow pragma
--------------
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
break memory safety! However, it can speed up assignments considerably,
because the semantics of Nim require deep copying of sequences and strings.
break memory safety! However, it can speed up assignments considerably,
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
structure:
structure:
.. code-block:: nim
type
NodeKind = enum nkLeaf, nkInner
Node {.final, shallow.} = object
case kind: NodeKind
of nkLeaf:
of nkLeaf:
strVal: string
of nkInner:
of nkInner:
children: seq[Node]
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
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
with the given content. Compilation does not necessarily abort after an error
though.
though.
The ``error`` pragma can also be used to
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
operation is valid due to overloading and type conversions:
operation is valid due to overloading and type conversions:
.. code-block:: nim
## 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:
.. code-block:: nim
template myassert*(cond: expr, msg = "") =
if not cond:
# 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
--------------------
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
statement:
.. code-block:: nim
case myInt
of 0:
of 0:
echo "most common case"
of 1:
of 1:
{.linearScanEnd.}
echo "second most common case"
of 2: echo "unlikely: use branch table"
else: echo "unlikely too: use branch table for ", myInt
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
values first, so that the CPU's branch predictor has a good chance to succeed
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
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
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
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
-------------------
The ``computedGoto`` pragma can be used to tell the compiler how to
compile a Nim `case`:idx: in a ``while true`` statement.
The ``computedGoto`` pragma can be used to tell the compiler how to
compile a Nim `case`:idx: in a ``while true`` statement.
Syntactically it has to be used as a statement inside the loop:
.. code-block:: nim
@@ -278,21 +278,21 @@ Syntactically it has to be used as a statement inside the loop:
of enumE:
break
inc(pc)
vm()
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.
unroll pragma
-------------
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
proc searchChar(s: string, c: char): int =
proc searchChar(s: string, c: char): int =
for i in 0 .. s.high:
{.unroll: 4.}
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
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.
Example:
@@ -461,9 +461,9 @@ Example:
pragma pragma
-------------
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
defined pragmas are in a different module-wide scope than all other symbols.
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
defined pragmas are in a different module-wide scope than all other symbols.
They cannot be imported from a module.
Example:
@@ -473,8 +473,8 @@ Example:
{.pragma: rtl, exportc, dynlib, cdecl.}
else:
{.pragma: rtl, importc, dynlib: "client.dll", cdecl.}
proc p*(a, b: int): int {.rtl.} =
proc p*(a, b: int): int {.rtl.} =
result = a+b
In the example a new pragma named ``rtl`` is introduced that either imports

View File

@@ -1,16 +1,16 @@
Threads
=======
To enable thread support the ``--threads:on`` command line switch needs to
be used. The ``system`` module then contains several threading primitives.
See the `threads <threads.html>`_ and `channels <channels.html>`_ modules
To enable thread support the ``--threads:on`` command line switch needs to
be used. The ``system`` module then contains several threading primitives.
See the `threads <threads.html>`_ and `channels <channels.html>`_ modules
for the low level thread API. There are also high level parallelism constructs
available. See `spawn`_ for further details.
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
collected) heap and sharing of memory is restricted to global variables. This
helps to prevent race conditions. GC efficiency is improved quite a lot,
programming languages (C, Pascal, Java): Each thread has its own (garbage
collected) heap and sharing of memory is restricted to global variables. This
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.
Memory allocation requires no lock at all! This design easily scales to massive
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
``thread`` pragma for reasons of readability. The compiler checks for
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.
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``.
@@ -34,7 +34,7 @@ GC safety
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
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,
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*.
Routines that are imported from C are always assumed to be ``gcsafe``.
To enable the GC-safety checking the ``--threadAnalysis:on`` command line
switch must 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
will always be performed.
To disable the GC-safety checking the ``--threadAnalysis:off`` command line
switch can be used. This is a temporary workaround to ease the porting effort
from old code to the new threading model.
Future directions:
@@ -59,13 +58,13 @@ Future directions:
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:
.. code-block:: nim
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
be replicated at thread creation.)
@@ -73,7 +72,7 @@ be replicated at thread creation.)
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 terminates the whole *process*!
@@ -82,7 +81,7 @@ in one thread terminates the whole *process*!
Parallel & Spawn
================
Nim has two flavors of parallelism:
Nim has two flavors of parallelism:
1) `Structured`:idx: parallelism via the ``parallel`` statement.
2) `Unstructured`:idx: parallelism via the standalone ``spawn`` statement.
@@ -115,7 +114,7 @@ Spawn statement
proc processLine(line: string) =
discard "do some heavy lifting here"
for x in lines("myinput.txt"):
spawn processLine(x)
sync()
@@ -144,7 +143,7 @@ wait on multiple flow variables at the same time:
.. code-block:: nim
import threadpool, ...
# wait until 2 out of 3 servers received the update:
proc main =
var responses = newSeq[RawFlowVar](3)
@@ -203,8 +202,7 @@ restrictions / changes:
the ``parallel`` section. This is called the *immutability check*. Currently
it is not specified what exactly "complex location" means. We need to make
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*.
* Slices are optimized so that no copy is performed. This optimization is not
yet performed for ordinary slices outside of a ``parallel`` section. Slices
are also special in that they currently do not support negative indexes!
yet performed for ordinary slices outside of a ``parallel`` section.

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