documentation improvements
This commit is contained in:
parent
0117f494ec
commit
783273032f
8 changed files with 100 additions and 72 deletions
|
|
@ -31,5 +31,5 @@ The documentation consists of several documents:
|
||||||
this if you want to hack the compiler.
|
this if you want to hack the compiler.
|
||||||
|
|
||||||
- | `Index <theindex.html>`_
|
- | `Index <theindex.html>`_
|
||||||
| The generated index. Often the quickest way to find the piece of
|
| The generated index. **Index + (Ctrl+F) == Joy**
|
||||||
information you need.
|
|
||||||
|
|
|
||||||
103
doc/manual.txt
103
doc/manual.txt
|
|
@ -193,18 +193,19 @@ contain the following `escape sequences`:idx:\ :
|
||||||
``\\`` `backslash`:idx:
|
``\\`` `backslash`:idx:
|
||||||
``\"`` `quotation mark`:idx:
|
``\"`` `quotation mark`:idx:
|
||||||
``\'`` `apostrophe`:idx:
|
``\'`` `apostrophe`:idx:
|
||||||
``\d+`` `character with decimal value d`:idx:;
|
``\`` '0'..'9'+ `character with decimal value d`:idx:;
|
||||||
all decimal digits directly
|
all decimal digits directly
|
||||||
following are used for the character
|
following are used for the character
|
||||||
``\a`` `alert`:idx:
|
``\a`` `alert`:idx:
|
||||||
``\b`` `backspace`:idx:
|
``\b`` `backspace`:idx:
|
||||||
``\e`` `escape`:idx: `[ESC]`:idx:
|
``\e`` `escape`:idx: `[ESC]`:idx:
|
||||||
``\xHH`` `character with hex value HH`:idx:;
|
``\x`` HH `character with hex value HH`:idx:;
|
||||||
exactly two hex digits are allowed
|
exactly two hex digits are allowed
|
||||||
================== ===================================================
|
================== ===================================================
|
||||||
|
|
||||||
|
|
||||||
Strings in Nimrod may contain any 8-bit value, except embedded zeros.
|
Strings in Nimrod may contain any 8-bit value, even embedded zeros. However
|
||||||
|
some operations may interpret the first binary zero as terminator.
|
||||||
|
|
||||||
|
|
||||||
Triple quoted string literals
|
Triple quoted string literals
|
||||||
|
|
@ -947,44 +948,44 @@ To deal with untraced memory, the procedures ``alloc``, ``dealloc`` and
|
||||||
further information.
|
further information.
|
||||||
|
|
||||||
If a reference points to *nothing*, it has the value ``nil``.
|
If a reference points to *nothing*, it has the value ``nil``.
|
||||||
|
|
||||||
Special care has to be taken if an untraced object contains traced objects like
|
Special care has to be taken if an untraced object contains traced objects like
|
||||||
traced references, strings or sequences: in order to free everything properly,
|
traced references, strings or sequences: in order to free everything properly,
|
||||||
the built-in procedure ``GCunref`` has to be called before freeing the untraced
|
the built-in procedure ``GCunref`` has to be called before freeing the untraced
|
||||||
memory manually:
|
memory manually:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
type
|
type
|
||||||
TData = tuple[x, y: int, s: string]
|
TData = tuple[x, y: int, s: string]
|
||||||
|
|
||||||
# allocate memory for TData on the heap:
|
# allocate memory for TData on the heap:
|
||||||
var d = cast[ptr TData](alloc0(sizeof(TData)))
|
var d = cast[ptr TData](alloc0(sizeof(TData)))
|
||||||
|
|
||||||
# create a new string on the garbage collected heap:
|
# create a new string on the garbage collected heap:
|
||||||
d.s = "abc"
|
d.s = "abc"
|
||||||
|
|
||||||
# tell the GC that the string is not needed anymore:
|
# tell the GC that the string is not needed anymore:
|
||||||
GCunref(d.s)
|
GCunref(d.s)
|
||||||
|
|
||||||
# free the memory:
|
# free the memory:
|
||||||
dealloc(d)
|
dealloc(d)
|
||||||
|
|
||||||
Without the ``GCunref`` call the memory allocated for the ``d.s`` string would
|
Without the ``GCunref`` call the memory allocated for the ``d.s`` string would
|
||||||
never be freed. The example also demonstrates two important features for low
|
never be freed. The example also demonstrates two important features for low
|
||||||
level programming: the ``sizeof`` proc returns the size of a type or value
|
level programming: the ``sizeof`` proc returns the size of a type or value
|
||||||
in bytes. The ``cast`` operator can circumvent the type system: the compiler
|
in bytes. The ``cast`` operator can circumvent the type system: the compiler
|
||||||
is forced to treat the result of the ``alloc0`` call (which returns an untyped
|
is forced to treat the result of the ``alloc0`` call (which returns an untyped
|
||||||
pointer) as if it would have the type ``ptr TData``. Casting should only be
|
pointer) as if it would have the type ``ptr TData``. Casting should only be
|
||||||
done if it is unavoidable: it breaks type safety and bugs can lead to
|
done if it is unavoidable: it breaks type safety and bugs can lead to
|
||||||
mysterious crashes.
|
mysterious crashes.
|
||||||
|
|
||||||
**Note**: The example only works because the memory is initialized with zero
|
**Note**: The example only works because the memory is initialized with zero
|
||||||
(``alloc0`` instead of ``alloc`` does this): ``d.s`` is thus initialized to
|
(``alloc0`` instead of ``alloc`` does this): ``d.s`` is thus initialized to
|
||||||
``nil`` which the string assignment can handle. You need to know low level
|
``nil`` which the string assignment can handle. You need to know low level
|
||||||
details like this when mixing garbage collected data with unmanaged memory.
|
details like this when mixing garbage collected data with unmanaged memory.
|
||||||
|
|
||||||
.. XXX finalizers for traced objects
|
.. XXX finalizers for traced objects
|
||||||
|
|
||||||
|
|
||||||
Procedural type
|
Procedural type
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|
@ -1750,17 +1751,17 @@ Syntax::
|
||||||
The direct embedding of `assembler`:idx: code into Nimrod code is supported
|
The direct embedding of `assembler`:idx: code into Nimrod code is supported
|
||||||
by the unsafe ``asm`` statement. Identifiers in the assembler code that refer to
|
by the unsafe ``asm`` statement. Identifiers in the assembler code that refer to
|
||||||
Nimrod identifiers shall be enclosed in a special character which can be
|
Nimrod identifiers shall be enclosed in a special character which can be
|
||||||
specified in the statement's pragmas. The default special character is ``'`'``:
|
specified in the statement's pragmas. The default special character is ``'`'``:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
proc addInt(a, b: int): int {.pure.} =
|
proc addInt(a, b: int): int {.pure.} =
|
||||||
# a in eax, and b in edx
|
# a in eax, and b in edx
|
||||||
asm """
|
asm """
|
||||||
mov eax, `a`
|
mov eax, `a`
|
||||||
add eax, `b`
|
add eax, `b`
|
||||||
jno theEnd
|
jno theEnd
|
||||||
call `raiseOverflow`
|
call `raiseOverflow`
|
||||||
theEnd:
|
theEnd:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
If expression
|
If expression
|
||||||
|
|
@ -2809,7 +2810,7 @@ a dynamic library (``.dll`` files for Windows, ``lib*.so`` files for UNIX). The
|
||||||
non-optional argument has to be the name of the dynamic library:
|
non-optional argument has to be the name of the dynamic library:
|
||||||
|
|
||||||
.. code-block:: Nimrod
|
.. code-block:: Nimrod
|
||||||
proc gtk_image_new(): PGtkWidget {.
|
proc gtk_image_new(): PGtkWidget {.
|
||||||
cdecl, dynlib: "libgtk-x11-2.0.so", importc.}
|
cdecl, dynlib: "libgtk-x11-2.0.so", importc.}
|
||||||
|
|
||||||
In general, importing a dynamic library does not require any special linker
|
In general, importing a dynamic library does not require any special linker
|
||||||
|
|
|
||||||
11
doc/tut1.txt
11
doc/tut1.txt
|
|
@ -17,11 +17,13 @@ Introduction
|
||||||
|
|
||||||
|
|
||||||
This document is a tutorial for the programming language *Nimrod*. After this
|
This document is a tutorial for the programming language *Nimrod*. After this
|
||||||
tutorial you will have a decent knowledge about Nimrod. This tutorial assumes
|
tutorial you will have a decent knowledge of Nimrod. This tutorial assumes
|
||||||
that you are familiar with basic programming concepts like variables, types
|
that you are familiar with basic programming concepts like variables, types
|
||||||
or statements.
|
or statements.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The first program
|
The first program
|
||||||
=================
|
=================
|
||||||
|
|
||||||
|
|
@ -44,10 +46,15 @@ appending them after the filename::
|
||||||
|
|
||||||
nimrod compile --run greetings.nim arg1 arg2
|
nimrod compile --run greetings.nim arg1 arg2
|
||||||
|
|
||||||
The most used commands and switches have abbreviations, so you can also use::
|
Commonly used commands and switches have abbreviations, so you can also use::
|
||||||
|
|
||||||
nimrod c -r greetings.nim
|
nimrod c -r greetings.nim
|
||||||
|
|
||||||
|
To compile a `release`:idx: version use::
|
||||||
|
|
||||||
|
nimrod c -d:release greetings.nim
|
||||||
|
|
||||||
|
|
||||||
Though it should be pretty obvious what the program does, I will explain the
|
Though it should be pretty obvious what the program does, I will explain the
|
||||||
syntax: statements which are not indented are executed when the program
|
syntax: statements which are not indented are executed when the program
|
||||||
starts. Indentation is Nimrod's way of grouping statements. Indentation is
|
starts. Indentation is Nimrod's way of grouping statements. Indentation is
|
||||||
|
|
|
||||||
|
|
@ -12,15 +12,31 @@
|
||||||
|
|
||||||
import streams
|
import streams
|
||||||
|
|
||||||
proc load*[T](s: PStream, data: var T) {.magic: "Load".}
|
proc load*[T](s: PStream, data: var T) =
|
||||||
## loads `data` from the stream `s`. Raises `EIO` in case of an error.
|
## loads `data` from the stream `s`. Raises `EIO` in case of an error.
|
||||||
|
|
||||||
proc store*[T](s: PStream, data: T) {.magic: "Store".}
|
proc store*[T](s: PStream, data: T) =
|
||||||
## stores `data` into the stream `s`. Raises `EIO` in case of an error.
|
## stores `data` into the stream `s`. Raises `EIO` in case of an error.
|
||||||
|
|
||||||
|
|
||||||
proc reprInt(x: int64): string {.compilerproc.} = return $x
|
type
|
||||||
proc reprFloat(x: float): string {.compilerproc.} = return $x
|
TTypeInfo = distinct whatever
|
||||||
|
|
||||||
|
TValue = object
|
||||||
|
t: TTypeInfo
|
||||||
|
x: pointer
|
||||||
|
|
||||||
|
|
||||||
|
proc rtti[T](x: T): TTypeInfo {.magic: "rtti".}
|
||||||
|
|
||||||
|
proc `[]` (a: TValue, i: int): TValue =
|
||||||
|
## works for arrays, objects, etc.
|
||||||
|
|
||||||
|
proc `[]=` (a: TValue, i: int, x: TValue) =
|
||||||
|
##
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
proc reprPointer(x: pointer): string {.compilerproc.} =
|
proc reprPointer(x: pointer): string {.compilerproc.} =
|
||||||
var buf: array [0..59, char]
|
var buf: array [0..59, char]
|
||||||
|
|
|
||||||
|
|
@ -284,7 +284,7 @@ proc fileNewer*(a, b: string): bool {.rtl, extern: "nos$1".} =
|
||||||
result = getLastModificationTime(a) - getLastModificationTime(b) > 0
|
result = getLastModificationTime(a) - getLastModificationTime(b) > 0
|
||||||
|
|
||||||
proc getCurrentDir*(): string {.rtl, extern: "nos$1".} =
|
proc getCurrentDir*(): string {.rtl, extern: "nos$1".} =
|
||||||
## Returns the current working directory.
|
## Returns the `current working directory`:idx:.
|
||||||
const bufsize = 512 # should be enough
|
const bufsize = 512 # should be enough
|
||||||
result = newString(bufsize)
|
result = newString(bufsize)
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
|
|
@ -298,7 +298,7 @@ proc getCurrentDir*(): string {.rtl, extern: "nos$1".} =
|
||||||
OSError()
|
OSError()
|
||||||
|
|
||||||
proc setCurrentDir*(newDir: string) {.inline.} =
|
proc setCurrentDir*(newDir: string) {.inline.} =
|
||||||
## Sets the current working directory; `EOS` is raised if
|
## Sets the `current working directory`:idx:; `EOS` is raised if
|
||||||
## `newDir` cannot been set.
|
## `newDir` cannot been set.
|
||||||
when defined(Windows):
|
when defined(Windows):
|
||||||
if SetCurrentDirectoryA(newDir) == 0'i32: OSError()
|
if SetCurrentDirectoryA(newDir) == 0'i32: OSError()
|
||||||
|
|
@ -661,7 +661,7 @@ proc executeShellCommand*(command: string): int {.deprecated.} =
|
||||||
result = csystem(command)
|
result = csystem(command)
|
||||||
|
|
||||||
proc execShellCmd*(command: string): int {.rtl, extern: "nos$1".} =
|
proc execShellCmd*(command: string): int {.rtl, extern: "nos$1".} =
|
||||||
## Executes a shell command.
|
## Executes a `shell command`:idx:.
|
||||||
##
|
##
|
||||||
## Command has the form 'program args' where args are the command
|
## Command has the form 'program args' where args are the command
|
||||||
## line arguments given to program. The proc returns the error code
|
## line arguments given to program. The proc returns the error code
|
||||||
|
|
@ -720,7 +720,7 @@ proc findEnvVar(key: string): int =
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
proc getEnv*(key: string): string =
|
proc getEnv*(key: string): string =
|
||||||
## Returns the value of the environment variable named `key`.
|
## Returns the value of the `environment variable`:idx: named `key`.
|
||||||
##
|
##
|
||||||
## If the variable does not exist, "" is returned. To distinguish
|
## If the variable does not exist, "" is returned. To distinguish
|
||||||
## whether a variable exists or it's value is just "", call
|
## whether a variable exists or it's value is just "", call
|
||||||
|
|
@ -740,7 +740,7 @@ proc existsEnv*(key: string): bool =
|
||||||
else: return findEnvVar(key) >= 0
|
else: return findEnvVar(key) >= 0
|
||||||
|
|
||||||
proc putEnv*(key, val: string) =
|
proc putEnv*(key, val: string) =
|
||||||
## Sets the value of the environment variable named `key` to `val`.
|
## Sets the value of the `environment variable`:idx: named `key` to `val`.
|
||||||
## If an error occurs, `EInvalidEnvVar` is raised.
|
## If an error occurs, `EInvalidEnvVar` is raised.
|
||||||
|
|
||||||
# Note: by storing the string in the environment sequence,
|
# Note: by storing the string in the environment sequence,
|
||||||
|
|
@ -770,15 +770,17 @@ iterator iterOverEnvironment*(): tuple[key, value: string] {.deprecated.} =
|
||||||
yield (copy(environment[i], 0, p-1), copy(environment[i], p+1))
|
yield (copy(environment[i], 0, p-1), copy(environment[i], p+1))
|
||||||
|
|
||||||
iterator envPairs*(): tuple[key, value: string] =
|
iterator envPairs*(): tuple[key, value: string] =
|
||||||
## Iterate over all environments variables. In the first component of the
|
## Iterate over all `environments variables`:idx:. In the first component
|
||||||
## tuple is the name of the current variable stored, in the second its value.
|
## of the tuple is the name of the current variable stored, in the second
|
||||||
|
## its value.
|
||||||
getEnvVarsC()
|
getEnvVarsC()
|
||||||
for i in 0..high(environment):
|
for i in 0..high(environment):
|
||||||
var p = find(environment[i], '=')
|
var p = find(environment[i], '=')
|
||||||
yield (copy(environment[i], 0, p-1), copy(environment[i], p+1))
|
yield (copy(environment[i], 0, p-1), copy(environment[i], p+1))
|
||||||
|
|
||||||
iterator walkFiles*(pattern: string): string =
|
iterator walkFiles*(pattern: string): string =
|
||||||
## Iterate over all the files that match the `pattern`.
|
## Iterate over all the files that match the `pattern`. On POSIX this uses
|
||||||
|
## the `glob`:idx: call.
|
||||||
##
|
##
|
||||||
## `pattern` is OS dependant, but at least the "\*.ext"
|
## `pattern` is OS dependant, but at least the "\*.ext"
|
||||||
## notation is supported.
|
## notation is supported.
|
||||||
|
|
@ -914,7 +916,7 @@ proc rawCreateDir(dir: string) =
|
||||||
OSError()
|
OSError()
|
||||||
|
|
||||||
proc createDir*(dir: string) {.rtl, extern: "nos$1".} =
|
proc createDir*(dir: string) {.rtl, extern: "nos$1".} =
|
||||||
## Creates the directory `dir`.
|
## Creates the `directory`:idx: `dir`.
|
||||||
##
|
##
|
||||||
## The directory may contain several subdirectories that do not exist yet.
|
## The directory may contain several subdirectories that do not exist yet.
|
||||||
## The full path is created. If this fails, `EOS` is raised. It does **not**
|
## The full path is created. If this fails, `EOS` is raised. It does **not**
|
||||||
|
|
@ -1122,13 +1124,13 @@ when defined(windows):
|
||||||
ownArgv: seq[string]
|
ownArgv: seq[string]
|
||||||
|
|
||||||
proc paramCount*(): int {.rtl, extern: "nos$1".} =
|
proc paramCount*(): int {.rtl, extern: "nos$1".} =
|
||||||
## Returns the number of command line arguments given to the
|
## Returns the number of `command line arguments`:idx: given to the
|
||||||
## application.
|
## application.
|
||||||
if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLineA())
|
if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLineA())
|
||||||
result = ownArgv.len-1
|
result = ownArgv.len-1
|
||||||
|
|
||||||
proc paramStr*(i: int): string {.rtl, extern: "nos$1".} =
|
proc paramStr*(i: int): string {.rtl, extern: "nos$1".} =
|
||||||
## Returns the `i`-th command line argument given to the
|
## Returns the `i`-th `command line argument`:idx: given to the
|
||||||
## application.
|
## application.
|
||||||
##
|
##
|
||||||
## `i` should be in the range `1..paramCount()`, else
|
## `i` should be in the range `1..paramCount()`, else
|
||||||
|
|
|
||||||
|
|
@ -205,6 +205,7 @@ proc `%` *(formatstr: string, a: openarray[string]): string {.noSideEffect,
|
||||||
##
|
##
|
||||||
## The substitution variables (the thing after the ``$``) are enumerated
|
## The substitution variables (the thing after the ``$``) are enumerated
|
||||||
## from 1 to ``a.len``.
|
## from 1 to ``a.len``.
|
||||||
|
## To produce a verbatim ``$``, use ``$$``.
|
||||||
## The notation ``$#`` can be used to refer to the next substitution variable:
|
## The notation ``$#`` can be used to refer to the next substitution variable:
|
||||||
##
|
##
|
||||||
## .. code-block:: nimrod
|
## .. code-block:: nimrod
|
||||||
|
|
|
||||||
|
|
@ -254,7 +254,7 @@ proc setIndexForSourceTerm(d: PDoc, name: PRstNode, id: int) =
|
||||||
|
|
||||||
proc renderIndexTerm(d: PDoc, n: PRstNode): PRope =
|
proc renderIndexTerm(d: PDoc, n: PRstNode): PRope =
|
||||||
inc(d.id)
|
inc(d.id)
|
||||||
result = dispF("<em id=\"$1\">$2</em>", "$2\\label{$1}",
|
result = dispF("<span id=\"$1\">$2</span>", "$2\\label{$1}",
|
||||||
[toRope(d.id), renderAux(d, n)])
|
[toRope(d.id), renderAux(d, n)])
|
||||||
var h = newRstNode(rnHyperlink)
|
var h = newRstNode(rnHyperlink)
|
||||||
var a = newRstNode(rnLeaf, d.indexValFilename & disp("#", "") & $d.id)
|
var a = newRstNode(rnLeaf, d.indexValFilename & disp("#", "") & $d.id)
|
||||||
|
|
@ -739,7 +739,7 @@ proc renderRstToOut(d: PDoc, n: PRstNode): PRope =
|
||||||
result = renderAux(d, n, disp("<cite>$1</cite>", "\\emph{$1}"))
|
result = renderAux(d, n, disp("<cite>$1</cite>", "\\emph{$1}"))
|
||||||
of rnIdx:
|
of rnIdx:
|
||||||
if d.theIndex == nil:
|
if d.theIndex == nil:
|
||||||
result = renderAux(d, n, disp("<em>$1</em>", "\\emph{$1}"))
|
result = renderAux(d, n, disp("<span>$1</span>", "\\emph{$1}"))
|
||||||
else:
|
else:
|
||||||
result = renderIndexTerm(d, n)
|
result = renderIndexTerm(d, n)
|
||||||
of rnInlineLiteral:
|
of rnInlineLiteral:
|
||||||
|
|
|
||||||
1
todo.txt
1
todo.txt
|
|
@ -1,6 +1,7 @@
|
||||||
- thread support: threadvar on Windows seems broken;
|
- thread support: threadvar on Windows seems broken;
|
||||||
add --deadlock_prevention:on|off switch
|
add --deadlock_prevention:on|off switch
|
||||||
- built-in serialization
|
- built-in serialization
|
||||||
|
- change how generalized raw string literals work
|
||||||
|
|
||||||
- we need a way to disable tests
|
- we need a way to disable tests
|
||||||
- deprecate ^ and make it available as operator
|
- deprecate ^ and make it available as operator
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue