Merge branch 'devel'
This commit is contained in:
commit
0be654efe1
41 changed files with 28591 additions and 20701 deletions
|
|
@ -12,19 +12,6 @@ Advanced commands:
|
|||
module dependency graph
|
||||
//dump dump all defined conditionals and search paths
|
||||
//check checks the project for syntax and semantic
|
||||
//idetools compiler support for IDEs: possible options:
|
||||
--track:FILE,LINE,COL track a file/cursor position
|
||||
--trackDirty:DIRTY_FILE,ORIG_FILE,LINE,COL
|
||||
track a file, currently not saved to disk
|
||||
--suggest suggest all possible symbols at position
|
||||
--def list all possible definitions at position
|
||||
--context list possible invokation context
|
||||
--usages list all usages of the symbol at position
|
||||
--eval evaluates an expression
|
||||
//serve start the compiler as a service mode (CAAS)
|
||||
--server.type:TYPE either stdin or tcp
|
||||
--server.port:PORT port for tcp mode, by default 6000
|
||||
--server.address:HOST binds to that address, by default ""
|
||||
|
||||
Advanced options:
|
||||
-o, --out:FILE set the output filename
|
||||
|
|
@ -48,7 +35,6 @@ Advanced options:
|
|||
--os:SYMBOL set the target operating system (cross-compilation)
|
||||
--cpu:SYMBOL set the target processor (cross-compilation)
|
||||
--debuginfo enables debug information
|
||||
--debugger:on|off turn Embedded Nim Debugger on|off
|
||||
-t, --passC:OPTION pass an option to the C compiler
|
||||
-l, --passL:OPTION pass an option to the linker
|
||||
--cincludes:DIR modify the C compiler header search path
|
||||
|
|
@ -66,7 +52,6 @@ Advanced options:
|
|||
--threadanalysis:on|off turn thread analysis on|off
|
||||
--tlsEmulation:on|off turn thread local storage emulation on|off
|
||||
--taintMode:on|off turn taint mode on|off
|
||||
--symbolFiles:on|off turn symbol files on|off (experimental)
|
||||
--implicitStatic:on|off turn implicit compile time evaluation on|off
|
||||
--patterns:on|off turn pattern matching on|off
|
||||
--skipCfg do not read the general configuration file
|
||||
|
|
@ -83,13 +68,11 @@ Advanced options:
|
|||
--dynlibOverride:SYMBOL marks SYMBOL so that dynlib:SYMBOL
|
||||
has no effect and can be statically linked instead;
|
||||
symbol matching is fuzzy so
|
||||
that --dynlibOverride:lua matches
|
||||
that --dynlibOverride:lua matches
|
||||
dynlib: "liblua.so.3"
|
||||
--listCmd list the commands used to execute external programs
|
||||
--parallelBuild=0|1|... perform a parallel build
|
||||
--parallelBuild:0|1|... perform a parallel build
|
||||
value = number of processors (0 for auto-detect)
|
||||
--verbosity:0|1|2|3 set Nim's verbosity level (1 is default)
|
||||
--cs:none|partial set case sensitivity level (default: none);
|
||||
do not use! this setting affects the whole language
|
||||
--experimental enable experimental language features
|
||||
-v, --version show detailed version information
|
||||
|
|
|
|||
|
|
@ -79,10 +79,3 @@ string str
|
|||
identifier ident
|
||||
indentation indent
|
||||
------------------- ------------ --------------------------------------
|
||||
|
||||
|
||||
Coding Guidelines
|
||||
=================
|
||||
|
||||
For coding guidelines see the `Internals of the Nim Compiler
|
||||
<intern.html#coding-guidelines>`_ documentation.
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
The AST in Nim
|
||||
=================
|
||||
This section describes how the AST is modelled with Nim's type system.
|
||||
The AST consists of nodes (``PNimrodNode``) with a variable number of
|
||||
The AST consists of nodes (``NimNode``) with a variable number of
|
||||
children. Each node has a field named ``kind`` which describes what the node
|
||||
contains:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
type
|
||||
TNimrodNodeKind = enum ## kind of a node; only explanatory
|
||||
NimNodeKind = enum ## kind of a node; only explanatory
|
||||
nnkNone, ## invalid node kind
|
||||
nnkEmpty, ## empty node
|
||||
nnkIdent, ## node contains an identifier
|
||||
|
|
@ -18,11 +18,11 @@ contains:
|
|||
nnkCaseStmt, ## node represents a case statement
|
||||
... ## many more
|
||||
|
||||
PNimrodNode = ref TNimrodNode
|
||||
TNimrodNode {.final.} = object
|
||||
case kind: TNimrodNodeKind ## the node's kind
|
||||
NimNode = ref NimNodeObj
|
||||
NimNodeObj = object
|
||||
case kind: NimNodeKind ## the node's kind
|
||||
of nnkNone, nnkEmpty, nnkNilLit:
|
||||
nil ## node contains no additional fields
|
||||
discard ## node contains no additional fields
|
||||
of nnkCharLit..nnkInt64Lit:
|
||||
intVal: biggestInt ## the int literal
|
||||
of nnkFloatLit..nnkFloat64Lit:
|
||||
|
|
@ -30,13 +30,13 @@ contains:
|
|||
of nnkStrLit..nnkTripleStrLit:
|
||||
strVal: string ## the string literal
|
||||
of nnkIdent:
|
||||
ident: TNimrodIdent ## the identifier
|
||||
ident: NimIdent ## the identifier
|
||||
of nnkSym:
|
||||
symbol: PNimrodSymbol ## the symbol (after symbol lookup phase)
|
||||
symbol: NimSymbol ## the symbol (after symbol lookup phase)
|
||||
else:
|
||||
sons: seq[PNimrodNode] ## the node's sons (or children)
|
||||
sons: seq[NimNode] ## the node's sons (or children)
|
||||
|
||||
For the ``PNimrodNode`` type, the ``[]`` operator has been overloaded:
|
||||
For the ``NimNode`` type, the ``[]`` operator has been overloaded:
|
||||
``n[i]`` is ``n``'s ``i``-th child.
|
||||
|
||||
To specify the AST for the different Nim constructs, the notation
|
||||
|
|
@ -73,10 +73,7 @@ Nim expression corresponding AST
|
|||
----------------- ---------------------------------------------
|
||||
|
||||
Identifiers are ``nnkIdent`` nodes. After the name lookup pass these nodes
|
||||
get transferred into ``nnkSym`` nodes. However, a macro receives an AST that
|
||||
has not been checked for semantics and thus the identifiers have not been
|
||||
looked up. Macros should deal with ``nnkIdent`` nodes and do not need to deal
|
||||
with ``nnkSym`` nodes.
|
||||
get transferred into ``nnkSym`` nodes.
|
||||
|
||||
|
||||
Calls/expressions
|
||||
|
|
@ -171,13 +168,13 @@ AST:
|
|||
nnkStrLit("hallo"))
|
||||
|
||||
|
||||
Dereference operator ``^``
|
||||
--------------------------
|
||||
Dereference operator ``[]``
|
||||
---------------------------
|
||||
|
||||
Concrete syntax:
|
||||
|
||||
.. code-block:: nim
|
||||
x^
|
||||
x[]
|
||||
|
||||
AST:
|
||||
|
||||
|
|
@ -573,4 +570,3 @@ Other node kinds are especially designed to make AST manipulations easier.
|
|||
These are explained here.
|
||||
|
||||
To be written.
|
||||
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ The JavaScript target doesn't have any further interfacing considerations
|
|||
since it also has garbage collection, but the C targets require you to
|
||||
initialize Nim's internals, which is done calling a ``NimMain`` function.
|
||||
Also, C code requires you to specify a forward declaration for functions or
|
||||
the compiler will asume certain types for the return value and parameters
|
||||
the compiler will assume certain types for the return value and parameters
|
||||
which will likely make your program crash at runtime.
|
||||
|
||||
The Nim compiler can generate a C interface header through the ``--header``
|
||||
|
|
@ -335,18 +335,18 @@ Nimcache and C like targets
|
|||
|
||||
The C like backends will place their temporary ``.c``, ``.cpp`` or ``.m`` files
|
||||
in the ``nimcache`` directory. The naming of these files follows the pattern
|
||||
``babelPackageName_`` + ``nimSource``:
|
||||
``nimblePackageName_`` + ``nimSource``:
|
||||
|
||||
* Filenames for modules imported from `Babel packages
|
||||
<https://github.com/nim-code/babel>`_ will end up with
|
||||
``babelPackageName_module.c``. For example, if you import the
|
||||
``argument_parser`` module from the same name Babel package you
|
||||
* Filenames for modules imported from `nimble packages
|
||||
<https://github.com/nim-lang/nimble>`_ will end up with
|
||||
``nimblePackageName_module.c``. For example, if you import the
|
||||
``argument_parser`` module from the same name nimble package you
|
||||
will end up with a ``argument_parser_argument_parser.c`` file
|
||||
under ``nimcache``. The name of the Babel package comes from the
|
||||
``proj.babel`` file, the actual contents are not read by the
|
||||
under ``nimcache``. The name of the nimble package comes from the
|
||||
``proj.nimble`` file, the actual contents are not read by the
|
||||
compiler.
|
||||
|
||||
* Filenames for non babel packages (like your project) will be
|
||||
* Filenames for non nimble packages (like your project) will be
|
||||
renamed from ``.nim`` to have the extension of your target backend
|
||||
(from now on ``.c`` for these examples), but otherwise nothing
|
||||
else will change. This will quickly break if your project consists
|
||||
|
|
@ -360,13 +360,13 @@ in the ``nimcache`` directory. The naming of these files follows the pattern
|
|||
module <system.html>`_ is always imported automatically. Same for
|
||||
the `hashes module <hashes.html>`_ which will be named
|
||||
``stdlib_hashes.c``. The ``stdlib_`` prefix comes from the *fake*
|
||||
``lib/stdlib.babel`` file.
|
||||
``lib/stdlib.nimble`` file.
|
||||
|
||||
To find the name of a Babel package the compiler searches for a ``*.babel``
|
||||
To find the name of a nimble package the compiler searches for a ``*.nimble``
|
||||
file in the parent directory hierarchy of whatever module you are compiling.
|
||||
Even if you are in a subdirectory of your project, a parent ``*.babel`` file
|
||||
Even if you are in a subdirectory of your project, a parent ``*.nimble`` file
|
||||
will influence the naming of the nimcache name. This means that on Unix systems
|
||||
creating the file ``~/foo.babel`` will automatically prefix all nimcache files
|
||||
creating the file ``~/foo.nimble`` will automatically prefix all nimcache files
|
||||
not part of another package with the string ``foo_``.
|
||||
|
||||
|
||||
|
|
@ -427,7 +427,7 @@ Custom data types
|
|||
-----------------
|
||||
|
||||
Just like strings, custom data types that are to be shared between Nim and
|
||||
the backend will need careful consideration of who controlls who. If you want
|
||||
the backend will need careful consideration of who controls who. If you want
|
||||
to hand a Nim reference to C code, you will need to use `GC_ref
|
||||
<system.html#GC_ref>`_ to mark the reference as used, so it does not get
|
||||
freed. And for the C backend you will need to expose the `GC_unref
|
||||
|
|
@ -456,11 +456,7 @@ can then attach a GC to this thread via
|
|||
|
||||
.. code-block:: nim
|
||||
|
||||
setStackBottom(addr(someLocal))
|
||||
initGC()
|
||||
|
||||
At the moment this support is still experimental so you need to expose these
|
||||
functions yourself or submit patches to request a public API.
|
||||
system.setupForeignThreadGc()
|
||||
|
||||
It is **not** safe to disable the garbage collector and enable it after the
|
||||
call from your background thread even if the code you are calling is short
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ Command:
|
|||
//compile, c compile project with default code generator (C)
|
||||
//doc generate the documentation for inputfile
|
||||
//doc2 generate the documentation for the whole project
|
||||
//i start Nim in interactive mode (limited)
|
||||
|
||||
Arguments:
|
||||
arguments are passed to the program being run (if --run option is selected)
|
||||
|
|
@ -14,7 +13,6 @@ Options:
|
|||
-p, --path:PATH add path to search paths
|
||||
-d, --define:SYMBOL define a conditional symbol
|
||||
-u, --undef:SYMBOL undefine a conditional symbol
|
||||
--symbol:SYMBOL declare a conditional symbol
|
||||
-f, --forceBuild force rebuilding of all modules
|
||||
--stackTrace:on|off turn stack tracing on|off
|
||||
--lineTrace:on|off turn line tracing on|off
|
||||
|
|
@ -31,10 +29,12 @@ Options:
|
|||
--infChecks:on|off turn Inf checks on|off
|
||||
--deadCodeElim:on|off whole program dead code elimination on|off
|
||||
--opt:none|speed|size optimize not at all or for speed|size
|
||||
Note: use -d:release for a release build!
|
||||
--debugger:native|endb use native debugger (gdb) | ENDB (experimental)
|
||||
--app:console|gui|lib|staticlib
|
||||
generate a console app|GUI app|DLL|static library
|
||||
-r, --run run the compiled program with given arguments
|
||||
--advanced show advanced command line switches
|
||||
-h, --help show this help
|
||||
|
||||
Note: Even single letter options require the colon: -p:PATH.
|
||||
Note, single letter options that take an argument require a colon. E.g. -p:PATH.
|
||||
|
|
|
|||
|
|
@ -31,13 +31,13 @@ documentation with only their well-documented code.
|
|||
Example:
|
||||
|
||||
.. code-block:: nim
|
||||
type TPerson* = object
|
||||
type Person* = object
|
||||
## This type contains a description of a person
|
||||
name: string
|
||||
age: int
|
||||
|
||||
Outputs::
|
||||
TPerson* = object
|
||||
Person* = object
|
||||
name: string
|
||||
age: int
|
||||
|
||||
|
|
@ -195,7 +195,7 @@ In the case of Nim's own documentation, the ``txt`` value is just a commit
|
|||
hash to append to a formatted URL to https://github.com/Araq/Nim. The
|
||||
``tools/nimweb.nim`` helper queries the current git commit hash during doc
|
||||
generation, but since you might be working on an unpublished repository, it
|
||||
also allows specifying a ``githash`` value in ``web/nim.ini`` to force a
|
||||
also allows specifying a ``githash`` value in ``web/website.ini`` to force a
|
||||
specific commit in the output.
|
||||
|
||||
|
||||
|
|
@ -268,8 +268,8 @@ The relationship of type to suffix is made by the proc ``complexName`` in the
|
|||
``compiler/docgen.nim`` file. Here are some examples of complex names for
|
||||
symbols in the `system module <system.html>`_.
|
||||
|
||||
* ``type TSignedInt = int | int8 | int16 | int32 | int64`` **=>**
|
||||
`#TSignedInt <system.html#TSignedInt>`_
|
||||
* ``type SignedInt = int | int8 | int16 | int32 | int64`` **=>**
|
||||
`#SignedInt <system.html#SignedInt>`_
|
||||
* ``var globalRaiseHook: proc (e: ref E_Base): bool {.nimcall.}`` **=>**
|
||||
`#globalRaiseHook <system.html#globalRaiseHook>`_
|
||||
* ``const NimVersion = "0.0.0"`` **=>**
|
||||
|
|
@ -307,7 +307,7 @@ columns is:
|
|||
Nim's rules (eg. \`^\` like in `the actors module
|
||||
<actors.html#^,ptr.TChannel[T]>`_).
|
||||
2. Base filename plus anchor hyper link (eg.
|
||||
``algorithm.html#*,int,TSortOrder``).
|
||||
``algorithm.html#*,int,SortOrder``).
|
||||
3. Optional human readable string to display as hyper link. If the value is not
|
||||
present or is the empty string, the hyper link will be rendered
|
||||
using the term. Prefix whitespace indicates that this entry is
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ The template engine is quite flexible. It is easy to produce a procedure that
|
|||
writes the template code directly to a file::
|
||||
|
||||
#! stdtmpl(emit="f.write") | standard
|
||||
#proc writeHTMLPage(f: TFile, title, currentTab, content: string,
|
||||
#proc writeHTMLPage(f: File, title, currentTab, content: string,
|
||||
# tabs: openArray[string]) =
|
||||
<head><title>$title</title></head>
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -87,14 +87,14 @@ is triggered.
|
|||
Time measurement
|
||||
----------------
|
||||
|
||||
The GC's way of measing time uses (see ``lib/system/timers.nim`` for the
|
||||
The GC's way of measuring time uses (see ``lib/system/timers.nim`` for the
|
||||
implementation):
|
||||
|
||||
1) ``QueryPerformanceCounter`` and ``QueryPerformanceFrequency`` on Windows.
|
||||
2) ``mach_absolute_time`` on Mac OS X.
|
||||
3) ``gettimeofday`` on Posix systems.
|
||||
|
||||
As such it supports a resolution of nano seconds internally; however the API
|
||||
As such it supports a resolution of nanoseconds internally; however the API
|
||||
uses microseconds for convenience.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,17 +3,13 @@ comma = ',' COMMENT?
|
|||
semicolon = ';' COMMENT?
|
||||
colon = ':' COMMENT?
|
||||
colcom = ':' COMMENT?
|
||||
|
||||
operator = OP0 | OP1 | OP2 | OP3 | OP4 | OP5 | OP6 | OP7 | OP8 | OP9 | OP10
|
||||
operator = OP0 | OP1 | OP2 | OP3 | OP4 | OP5 | OP6 | OP7 | OP8 | OP9
|
||||
| 'or' | 'xor' | 'and'
|
||||
| 'is' | 'isnot' | 'in' | 'notin' | 'of'
|
||||
| 'div' | 'mod' | 'shl' | 'shr' | 'not' | 'addr' | 'static' | '..'
|
||||
|
||||
| 'div' | 'mod' | 'shl' | 'shr' | 'not' | 'static' | '..'
|
||||
prefixOperator = operator
|
||||
|
||||
optInd = COMMENT?
|
||||
optPar = (IND{>} | IND{=})?
|
||||
|
||||
simpleExpr = arrowExpr (OP0 optInd arrowExpr)*
|
||||
arrowExpr = assignExpr (OP1 optInd assignExpr)*
|
||||
assignExpr = orExpr (OP2 optInd orExpr)*
|
||||
|
|
@ -26,20 +22,20 @@ plusExpr = mulExpr (OP8 optInd mulExpr)*
|
|||
mulExpr = dollarExpr (OP9 optInd dollarExpr)*
|
||||
dollarExpr = primary (OP10 optInd primary)*
|
||||
symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'=')+)+ '`'
|
||||
| IDENT
|
||||
| IDENT | 'addr' | 'type'
|
||||
indexExpr = expr
|
||||
indexExprList = indexExpr ^+ comma
|
||||
exprColonEqExpr = expr (':'|'=' expr)?
|
||||
exprList = expr ^+ comma
|
||||
dotExpr = expr '.' optInd ('type' | 'addr' | symbol)
|
||||
qualifiedIdent = symbol ('.' optInd ('type' | 'addr' | symbol))?
|
||||
dotExpr = expr '.' optInd symbol
|
||||
qualifiedIdent = symbol ('.' optInd symbol)?
|
||||
exprColonEqExprList = exprColonEqExpr (comma exprColonEqExpr)* (comma)?
|
||||
setOrTableConstr = '{' ((exprColonEqExpr comma)* | ':' ) '}'
|
||||
castExpr = 'cast' '[' optInd typeDesc optPar ']' '(' optInd expr optPar ')'
|
||||
parKeyw = 'discard' | 'include' | 'if' | 'while' | 'case' | 'try'
|
||||
| 'finally' | 'except' | 'for' | 'block' | 'const' | 'let'
|
||||
| 'when' | 'var' | 'mixin'
|
||||
par = '(' optInd (&parKeyw complexOrSimpleStmt ^+ ';'
|
||||
par = '(' optInd (&parKeyw complexOrSimpleStmt ^+ ';'
|
||||
| simpleExpr ('=' expr (';' complexOrSimpleStmt ^+ ';' )? )?
|
||||
| (':' expr)? (',' (exprColonEqExpr comma?)*)? )?
|
||||
optPar ')'
|
||||
|
|
@ -56,11 +52,11 @@ identOrLiteral = generalizedLit | symbol | literal
|
|||
tupleConstr = '(' optInd (exprColonEqExpr comma?)* optPar ')'
|
||||
arrayConstr = '[' optInd (exprColonEqExpr comma?)* optPar ']'
|
||||
primarySuffix = '(' (exprColonEqExpr comma?)* ')' doBlocks?
|
||||
| doBlocks
|
||||
| '.' optInd ('type' | 'addr' | symbol) generalizedLit?
|
||||
| '[' optInd indexExprList optPar ']'
|
||||
| '{' optInd indexExprList optPar '}'
|
||||
| &( '`'|IDENT|literal|'cast') expr # command syntax
|
||||
| doBlocks
|
||||
| '.' optInd symbol generalizedLit?
|
||||
| '[' optInd indexExprList optPar ']'
|
||||
| '{' optInd indexExprList optPar '}'
|
||||
| &( '`'|IDENT|literal|'cast'|'addr'|'type') expr # command syntax
|
||||
condExpr = expr colcom expr optInd
|
||||
('elif' expr colcom expr optInd)*
|
||||
'else' colcom expr
|
||||
|
|
@ -77,6 +73,7 @@ inlTupleDecl = 'tuple'
|
|||
[' optInd (identColonEquals (comma/semicolon)?)* optPar ']'
|
||||
extTupleDecl = 'tuple'
|
||||
COMMENT? (IND{>} identColonEquals (IND{=} identColonEquals)*)?
|
||||
tupleClass = 'tuple'
|
||||
paramList = '(' declColonEquals ^* (comma/semicolon) ')'
|
||||
paramListArrow = paramList? ('->' optInd typeDesc)?
|
||||
paramListColon = paramList? (':' optInd typeDesc)?
|
||||
|
|
@ -89,17 +86,16 @@ expr = (ifExpr
|
|||
| caseExpr
|
||||
| tryExpr)
|
||||
/ simpleExpr
|
||||
typeKeyw = 'var' | 'ref' | 'ptr' | 'shared' | 'type' | 'tuple'
|
||||
typeKeyw = 'var' | 'ref' | 'ptr' | 'shared' | 'tuple'
|
||||
| 'proc' | 'iterator' | 'distinct' | 'object' | 'enum'
|
||||
primary = typeKeyw typeDescK
|
||||
/ prefixOperator* identOrLiteral primarySuffix*
|
||||
/ 'addr' primary
|
||||
/ 'static' primary
|
||||
/ 'bind' primary
|
||||
typeDesc = simpleExpr
|
||||
typeDefAux = simpleExpr
|
||||
| 'generic' typeClass
|
||||
macroColon = ':' stmt? ( IND{=} 'of' exprList ':' stmt
|
||||
| 'concept' typeClass
|
||||
macroColon = ':' stmt? ( IND{=} 'of' exprList ':' stmt
|
||||
| IND{=} 'elif' expr ':' stmt
|
||||
| IND{=} 'except' exprList ':' stmt
|
||||
| IND{=} 'else' ':' stmt )*
|
||||
|
|
@ -167,7 +163,7 @@ objectCase = 'case' identWithPragma ':' typeDesc ':'? COMMENT?
|
|||
(IND{>} objectBranches DED
|
||||
| IND{=} objectBranches)
|
||||
objectPart = IND{>} objectPart^+IND{=} DED
|
||||
/ objectWhen / objectCase / 'nil' / declColonEquals
|
||||
/ objectWhen / objectCase / 'nil' / 'discard' / declColonEquals
|
||||
object = 'object' pragma? ('of' typeDesc)? COMMENT? objectPart
|
||||
typeClassParam = ('var')? symbol
|
||||
typeClass = typeClassParam ^* ',' (pragma)? ('of' typeDesc ^* ',')?
|
||||
|
|
@ -183,7 +179,7 @@ simpleStmt = ((returnStmt | raiseStmt | yieldStmt | discardStmt | breakStmt
|
|||
| continueStmt | pragmaStmt | importStmt | exportStmt | fromStmt
|
||||
| includeStmt | commentStmt) / exprStmt) COMMENT?
|
||||
complexOrSimpleStmt = (ifStmt | whenStmt | whileStmt
|
||||
| tryStmt | finallyStmt | exceptStmt | forStmt
|
||||
| tryStmt | forStmt
|
||||
| blockStmt | staticStmt | deferStmt | asmStmt
|
||||
| 'proc' routine
|
||||
| 'method' routine
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ integrations <https://github.com/Araq/Nim/wiki/Editor-Support>`_
|
|||
already available.
|
||||
|
||||
|
||||
Idetools invokation
|
||||
Idetools invocation
|
||||
===================
|
||||
|
||||
Specifying the location of the query
|
||||
|
|
@ -35,7 +35,7 @@ Specifying the location of the query
|
|||
|
||||
All of the available idetools commands require you to specify a
|
||||
query location through the ``--track`` or ``--trackDirty`` switches.
|
||||
The general idetools invokations are::
|
||||
The general idetools invocations are::
|
||||
|
||||
nim idetools --track:FILE,LINE,COL <switches> proj.nim
|
||||
|
||||
|
|
@ -129,7 +129,7 @@ the suggestions sorted first by scope (from innermost to outermost)
|
|||
and then by item name.
|
||||
|
||||
|
||||
Invokation context
|
||||
Invocation context
|
||||
------------------
|
||||
|
||||
The ``--context`` idetools switch is very similar to the suggestions
|
||||
|
|
@ -145,7 +145,7 @@ The ``--usages`` idetools switch lists all usages of the symbol at
|
|||
a position. IDEs can use this to find all the places in the file
|
||||
where the symbol is used and offer the user to rename it in all
|
||||
places at the same time. Again, a pure string based search and
|
||||
replace may catch symbols out of the scope of a funcion/loop.
|
||||
replace may catch symbols out of the scope of a function/loop.
|
||||
|
||||
For this kind of query the IDE will most likely ignore all the
|
||||
type/signature info provided by idetools and concentrate on the
|
||||
|
|
@ -163,7 +163,7 @@ running/debugged user project.
|
|||
Compiler as a service (CAAS)
|
||||
============================
|
||||
|
||||
The ocasional use of idetools is acceptable for things like
|
||||
The occasional use of idetools is acceptable for things like
|
||||
definitions, where the user puts the cursor on a symbol or double
|
||||
clicks it and after a second or two the IDE displays where that
|
||||
symbol is defined. Such latencies would be terrible for features
|
||||
|
|
@ -213,7 +213,7 @@ tab characters (``\t``). The values of each column are:
|
|||
``proj.symbolName``.
|
||||
4. Type/signature. For variables and enums this will contain the
|
||||
type of the symbol, for procs, methods and templates this will
|
||||
contain the full unique signature (e.g. ``proc (TFile)``).
|
||||
contain the full unique signature (e.g. ``proc (File)``).
|
||||
5. Full path to the file containing the symbol.
|
||||
6. Line where the symbol is located in the file. Lines start to
|
||||
count at **1**.
|
||||
|
|
@ -258,8 +258,8 @@ skEnumField
|
|||
|
||||
.. code-block:: nim
|
||||
Open(filename, fmWrite)
|
||||
--> col 2: system.TFileMode.fmWrite
|
||||
col 3: TFileMode
|
||||
--> col 2: system.FileMode.fmWrite
|
||||
col 3: FileMode
|
||||
col 7: ""
|
||||
|
||||
|
||||
|
|
@ -296,7 +296,7 @@ posterior instances of the iterator.
|
|||
text = "some text"
|
||||
letters = toSeq(runes(text))
|
||||
--> col 2: unicode.runes
|
||||
col 3: iterator (string): TRune
|
||||
col 3: iterator (string): Rune
|
||||
col 7: "iterates over any unicode character of the string `s`."
|
||||
|
||||
|
||||
|
|
@ -421,9 +421,9 @@ returned by idetools returns also the pragmas for the proc.
|
|||
| **Docstring**: docstring if available.
|
||||
|
||||
.. code-block:: nim
|
||||
Open(filename, fmWrite)
|
||||
open(filename, fmWrite)
|
||||
--> col 2: system.Open
|
||||
col 3: proc (var TFile, string, TFileMode, int): bool
|
||||
col 3: proc (var File, string, FileMode, int): bool
|
||||
col 7:
|
||||
"Opens a file named `filename` with given `mode`.
|
||||
|
||||
|
|
@ -487,9 +487,9 @@ skType
|
|||
|
||||
.. code-block:: nim
|
||||
proc writeTempFile() =
|
||||
var output: TFile
|
||||
--> col 2: system.TFile
|
||||
col 3: TFile
|
||||
var output: File
|
||||
--> col 2: system.File
|
||||
col 3: File
|
||||
col 7: ""
|
||||
|
||||
|
||||
|
|
@ -502,11 +502,11 @@ skVar
|
|||
|
||||
.. code-block:: nim
|
||||
proc writeTempFile() =
|
||||
var output: TFile
|
||||
var output: File
|
||||
output.open("/tmp/somefile", fmWrite)
|
||||
output.write("test")
|
||||
--> col 2: $MODULE.writeTempFile.output
|
||||
col 3: TFile
|
||||
col 3: File
|
||||
col 7: ""
|
||||
|
||||
|
||||
|
|
@ -533,10 +533,10 @@ run it manually. First you have to compile the tester::
|
|||
Running the ``caasdriver`` without parameters will attempt to process
|
||||
all the test cases in all three operation modes. If a test succeeds
|
||||
nothing will be printed and the process will exit with zero. If any
|
||||
test fails, the specific line of the test preceeding the failure
|
||||
test fails, the specific line of the test preceding the failure
|
||||
and the failure itself will be dumped to stdout, along with a final
|
||||
indicator of the success state and operation mode. You can pass the
|
||||
parameter ``verbose`` to force all output even on successfull tests.
|
||||
parameter ``verbose`` to force all output even on successful tests.
|
||||
|
||||
The normal operation mode is called ``ProcRun`` and it involves
|
||||
starting a process for each command or query, similar to running
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ are also lots of procs that aid in debugging:
|
|||
debug(someType)
|
||||
echo symbol.name.s
|
||||
debug(symbol)
|
||||
# pretty prints the nimrod ast, but annotates symbol IDs:
|
||||
# pretty prints the Nim ast, but annotates symbol IDs:
|
||||
echo renderTree(someNode, {renderIds})
|
||||
if n.info ?? "temp.nim":
|
||||
# only output when it comes from "temp.nim"
|
||||
|
|
@ -145,6 +145,19 @@ are also lots of procs that aid in debugging:
|
|||
# why does it process temp.nim here?
|
||||
writeStackTrace()
|
||||
|
||||
To create a new compiler for each run, use ``koch temp``::
|
||||
|
||||
./koch temp c /tmp/test.nim
|
||||
|
||||
``koch temp`` creates a debug build of the compiler, which is useful
|
||||
to create stacktraces for compiler debugging.
|
||||
|
||||
``koch temp`` returns 125 as the exit code in case the compiler
|
||||
compilation fails. This exit code tells ``git bisect`` to skip the
|
||||
current commit.::
|
||||
|
||||
git bisect start bad-commit good-commit
|
||||
git bisect ./koch -r c test-source.nim
|
||||
|
||||
The compiler's architecture
|
||||
===========================
|
||||
|
|
@ -223,7 +236,7 @@ too. Type converters fall into this category:
|
|||
|
||||
If in the above example module ``B`` is re-compiled, but ``A`` is not then
|
||||
``B`` needs to be aware of ``toBool`` even though ``toBool`` is not referenced
|
||||
in ``B`` *explicitely*.
|
||||
in ``B`` *explicitly*.
|
||||
|
||||
Both the multi method and the type converter problems are solved by storing
|
||||
them in special sections in the ROD file that are loaded *unconditionally*
|
||||
|
|
@ -357,7 +370,7 @@ needed as the data structures needs to be rebuilt periodically anyway.
|
|||
|
||||
Complete traversal is done in this way::
|
||||
|
||||
for each page decriptor d:
|
||||
for each page descriptor d:
|
||||
for each bit in d:
|
||||
if bit == 1:
|
||||
traverse the pointer belonging to this bit
|
||||
|
|
@ -393,7 +406,7 @@ The generated code looks roughly like this:
|
|||
setRef(&r->left)
|
||||
}
|
||||
|
||||
Note that for systems with a continous stack (which most systems have)
|
||||
Note that for systems with a continuous stack (which most systems have)
|
||||
the check whether the ref is on the stack is very cheap (only two
|
||||
comparisons).
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
addr and as asm atomic
|
||||
bind block break
|
||||
case cast const continue converter
|
||||
case cast concept const continue converter
|
||||
defer discard distinct div do
|
||||
elif else end enum except export
|
||||
finally for from func
|
||||
|
|
|
|||
70
doc/lib.txt
70
doc/lib.txt
|
|
@ -37,7 +37,7 @@ Core
|
|||
|
||||
* `unsigned <unsigned.html>`_
|
||||
This module implements basic arithmetic operators for unsigned integers.
|
||||
To discourage users from using unsigned integers, it's not part
|
||||
To discourage users from using unsigned integers, it's not part
|
||||
of ``system``, but an extra import.
|
||||
|
||||
* `threads <threads.html>`_
|
||||
|
|
@ -45,7 +45,7 @@ Core
|
|||
import it explicitly.
|
||||
|
||||
* `channels <channels.html>`_
|
||||
Nim message passing support for threads. **Note**: This is part of the
|
||||
Nim message passing support for threads. **Note**: This is part of the
|
||||
system module. Do not import it explicitly.
|
||||
|
||||
* `locks <locks.html>`_
|
||||
|
|
@ -55,7 +55,7 @@ Core
|
|||
Contains the AST API and documentation of Nim for writing macros.
|
||||
|
||||
* `typeinfo <typeinfo.html>`_
|
||||
Provides (unsafe) access to Nim's run time type information.
|
||||
Provides (unsafe) access to Nim's run time type information.
|
||||
|
||||
* `typetraits <typetraits.html>`_
|
||||
This module defines compile-time reflection procs for working with types.
|
||||
|
|
@ -110,9 +110,9 @@ String handling
|
|||
|
||||
* `unicode <unicode.html>`_
|
||||
This module provides support to handle the Unicode UTF-8 encoding.
|
||||
|
||||
|
||||
* `encodings <encodings.html>`_
|
||||
Converts between different character encodings. On UNIX, this uses
|
||||
Converts between different character encodings. On UNIX, this uses
|
||||
the ``iconv`` library, on Windows the Windows API.
|
||||
|
||||
* `pegs <pegs.html>`_
|
||||
|
|
@ -159,7 +159,7 @@ Generic Operating System Services
|
|||
may provide other implementations for this standard stream interface.
|
||||
|
||||
* `marshal <marshal.html>`_
|
||||
Contains procs for serialization and deseralization of arbitrary Nim
|
||||
Contains procs for serialization and deseralization of arbitrary Nim
|
||||
data structures.
|
||||
|
||||
* `terminal <terminal.html>`_
|
||||
|
|
@ -168,13 +168,16 @@ Generic Operating System Services
|
|||
sequences and does not depend on any other module.
|
||||
|
||||
* `memfiles <memfiles.html>`_
|
||||
This module provides support for memory mapped files (Posix's ``mmap``)
|
||||
This module provides support for memory mapped files (Posix's ``mmap``)
|
||||
on the different operating systems.
|
||||
|
||||
* `fsmonitor <fsmonitor.html>`_
|
||||
This module implements the ability to monitor a directory/file for changes
|
||||
using Posix's inotify API.
|
||||
|
||||
* `asyncfile <asyncfile.html>`_
|
||||
This module implements asynchronous file reading and writing using
|
||||
``asyncdispatch``.
|
||||
|
||||
Math libraries
|
||||
--------------
|
||||
|
|
@ -185,10 +188,19 @@ Math libraries
|
|||
* `complex <complex.html>`_
|
||||
This module implements complex numbers and their mathematical operations.
|
||||
|
||||
* `rationals <rationals.html>`_
|
||||
This module implements rational numbers and their mathematical operations.
|
||||
|
||||
* `fenv <fenv.html>`_
|
||||
Floating-point environment. Handling of floating-point rounding and
|
||||
exceptions (overflow, zero-devide, etc.).
|
||||
|
||||
* `basic2d <basic2d.html>`_
|
||||
Basic 2d support with vectors, points, matrices and some basic utilities.
|
||||
|
||||
* `basic3d <basic3d.html>`_
|
||||
Basic 3d support with vectors, points, matrices and some basic utilities.
|
||||
|
||||
|
||||
Internet Protocols and Support
|
||||
------------------------------
|
||||
|
|
@ -216,10 +228,7 @@ Internet Protocols and Support
|
|||
This module implements a simple HTTP client.
|
||||
|
||||
* `smtp <smtp.html>`_
|
||||
This module implement a simple SMTP client.
|
||||
|
||||
* `irc <irc.html>`_
|
||||
This module implements an asynchronous IRC client.
|
||||
This module implement a simple SMTP client.
|
||||
|
||||
* `ftpclient <ftpclient.html>`_
|
||||
This module implements an FTP client.
|
||||
|
|
@ -337,7 +346,7 @@ XML Processing
|
|||
This module parses an HTML document and creates its XML tree representation.
|
||||
|
||||
* `htmlgen <htmlgen.html>`_
|
||||
This module implements a simple XML and HTML code
|
||||
This module implements a simple XML and HTML code
|
||||
generator. Each commonly used HTML tag has a corresponding macro
|
||||
that generates a string with its HTML representation.
|
||||
|
||||
|
|
@ -367,12 +376,12 @@ Miscellaneous
|
|||
-------------
|
||||
|
||||
* `events <events.html>`_
|
||||
This module implements an event system that is not dependant on external
|
||||
This module implements an event system that is not dependent on external
|
||||
graphical toolkits.
|
||||
|
||||
* `oids <oids.html>`_
|
||||
An OID is a global ID that consists of a timestamp,
|
||||
a unique counter and a random value. This combination should suffice to
|
||||
a unique counter and a random value. This combination should suffice to
|
||||
produce a globally distributed unique ID. This implementation was extracted
|
||||
from the Mongodb interface and it thus binary compatible with a Mongo OID.
|
||||
|
||||
|
|
@ -444,12 +453,8 @@ Other
|
|||
* `zipfiles <zipfiles.html>`_
|
||||
This module implements a zip archive creator/reader/modifier.
|
||||
|
||||
* `web <web.html>`_
|
||||
This module contains simple high-level procedures for dealing with the
|
||||
Web like loading the contents of a Web page from an URL.
|
||||
|
||||
* `ssl <ssl.html>`_
|
||||
This module provides an easy to use sockets-style
|
||||
This module provides an easy to use sockets-style
|
||||
Nim interface to the OpenSSL library.
|
||||
|
||||
* `rdstdin <rdstdin.html>`_
|
||||
|
|
@ -468,12 +473,16 @@ Windows specific
|
|||
|
||||
* `windows <windows.html>`_
|
||||
Contains a wrapper for the Win32 API.
|
||||
* `winlean <winlean.html>`_
|
||||
Contains a wrapper for a small subset of the Win32 API.
|
||||
* `shellapi <shellapi.html>`_
|
||||
Contains a wrapper for the ``shellapi.h`` header.
|
||||
* `shfolder <shfolder.html>`_
|
||||
Contains a wrapper for the ``shfolder.h`` header.
|
||||
* `mmsystem <mmsystem.html>`_
|
||||
Contains a wrapper for the ``mmsystem.h`` header.
|
||||
* `psapi <psapi.html>`_
|
||||
Contains a wrapper for the ``psapi.h`` header.
|
||||
* `nb30 <nb30.html>`_
|
||||
This module contains the definitions for portable NetBIOS 3.0 support.
|
||||
|
||||
|
|
@ -500,25 +509,6 @@ Regular expressions
|
|||
Wrapper for the TRE library.
|
||||
|
||||
|
||||
Graphics libraries
|
||||
------------------
|
||||
|
||||
* `sdl <sdl.html>`_
|
||||
Part of the wrapper for SDL.
|
||||
* `sdl_gfx <sdl_gfx.html>`_
|
||||
Part of the wrapper for SDL.
|
||||
* `sdl_image <sdl_image.html>`_
|
||||
Part of the wrapper for SDL.
|
||||
* `sdl_mixer <sdl_mixer.html>`_
|
||||
Part of the wrapper for SDL.
|
||||
* `sdl_net <sdl_net.html>`_
|
||||
Part of the wrapper for SDL.
|
||||
* `sdl_ttf <sdl_ttf.html>`_
|
||||
Part of the wrapper for SDL.
|
||||
* `smpeg <smpeg.html>`_
|
||||
Part of the wrapper for SDL.
|
||||
|
||||
|
||||
GUI libraries
|
||||
-------------
|
||||
|
||||
|
|
@ -578,7 +568,7 @@ Data Compression and Archiving
|
|||
Scientific computing
|
||||
--------------------
|
||||
|
||||
* `libsvm <libsvm.html>`_
|
||||
* `libsvm <libsvm.html>`_
|
||||
Low level wrapper for `lib svm <http://www.csie.ntu.edu.tw/~cjlin/libsvm/>`_.
|
||||
|
||||
Nimble
|
||||
|
|
@ -586,7 +576,7 @@ Nimble
|
|||
|
||||
Nimble is a package manager for the Nim programming language.
|
||||
For instructions on how to install Nimble packages see
|
||||
`its README <https://github.com/nim-lang/babel#readme>`_.
|
||||
`its README <https://github.com/nim-lang/nimble#readme>`_.
|
||||
|
||||
Official packages
|
||||
-----------------
|
||||
|
|
|
|||
|
|
@ -25,9 +25,9 @@ with ``'``. An example::
|
|||
|
||||
ifStmt = 'if' expr ':' stmts ('elif' expr ':' stmts)* ('else' stmts)?
|
||||
|
||||
The binary ``^*`` operator is used as a shorthand for 0 or more occurances
|
||||
The binary ``^*`` operator is used as a shorthand for 0 or more occurrences
|
||||
separated by its second argument; likewise ``^+`` means 1 or more
|
||||
occurances: ``a ^+ b`` is short for ``a (b a)*``
|
||||
occurrences: ``a ^+ b`` is short for ``a (b a)*``
|
||||
and ``a ^* b`` is short for ``(a (b a)*)?``. Example::
|
||||
|
||||
arrayConstructor = '[' expr ^* ',' ']'
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ compatibility:
|
|||
|
||||
.. code-block:: nim
|
||||
type
|
||||
TCallback = proc (s: string) {.raises: [IOError].}
|
||||
Callback = proc (s: string) {.raises: [IOError].}
|
||||
var
|
||||
c: TCallback
|
||||
c: Callback
|
||||
|
||||
proc p(x: string) =
|
||||
raise newException(OSError, "OS")
|
||||
|
|
|
|||
|
|
@ -67,6 +67,41 @@ follows a ``(`` it has to be written as a one liner:
|
|||
let x = (try: parseInt("133a") except: -1)
|
||||
|
||||
|
||||
Except clauses
|
||||
--------------
|
||||
|
||||
Within an ``except`` clause, it is possible to use
|
||||
``getCurrentException`` to retrieve the exception that has been
|
||||
raised:
|
||||
|
||||
.. code-block:: nim
|
||||
try:
|
||||
# ...
|
||||
except IOError:
|
||||
let e = getCurrentException()
|
||||
# Now use "e"
|
||||
|
||||
Note that ``getCurrentException`` always returns a ``ref Exception``
|
||||
type. If a variable of the proper type is needed (in the example
|
||||
above, ``IOError``), one must convert it explicitly:
|
||||
|
||||
.. code-block:: nim
|
||||
try:
|
||||
# ...
|
||||
except IOError:
|
||||
let e = (ref IOError)(getCurrentException())
|
||||
# "e" is now of the proper type
|
||||
|
||||
However, this is seldom needed. The most common case is to extract an
|
||||
error message from ``e``, and for such situations it is enough to use
|
||||
``getCurrentExceptionMsg``:
|
||||
|
||||
.. code-block:: nim
|
||||
try:
|
||||
# ...
|
||||
except IOError:
|
||||
echo "I/O error: " & getCurrentExceptionMsg()
|
||||
|
||||
|
||||
Defer statement
|
||||
---------------
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ instructs the compiler to pass the type by value to procs:
|
|||
|
||||
.. code-block:: nim
|
||||
type
|
||||
TVector {.bycopy, pure.} = object
|
||||
Vector {.bycopy, pure.} = object
|
||||
x, y, z: float
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -9,17 +9,17 @@ The following example shows a generic binary tree can be modelled:
|
|||
|
||||
.. code-block:: nim
|
||||
type
|
||||
TBinaryTree[T] = object # TBinaryTree is a generic type with
|
||||
BinaryTreeObj[T] = object # BinaryTreeObj is a generic type with
|
||||
# with generic param ``T``
|
||||
le, ri: ref TBinaryTree[T] # left and right subtrees; may be nil
|
||||
le, ri: BinaryTree[T] # left and right subtrees; may be nil
|
||||
data: T # the data stored in a node
|
||||
PBinaryTree[T] = ref TBinaryTree[T] # a shorthand for notational convenience
|
||||
BinaryTree[T] = ref BinaryTreeObj[T] # a shorthand for notational convenience
|
||||
|
||||
proc newNode[T](data: T): PBinaryTree[T] = # constructor for a node
|
||||
proc newNode[T](data: T): BinaryTree[T] = # constructor for a node
|
||||
new(result)
|
||||
result.data = data
|
||||
|
||||
proc add[T](root: var PBinaryTree[T], n: PBinaryTree[T]) =
|
||||
proc add[T](root: var BinaryTree[T], n: BinaryTree[T]) =
|
||||
if root == nil:
|
||||
root = n
|
||||
else:
|
||||
|
|
@ -40,7 +40,7 @@ The following example shows a generic binary tree can be modelled:
|
|||
return
|
||||
it = it.ri
|
||||
|
||||
iterator inorder[T](root: PBinaryTree[T]): T =
|
||||
iterator inorder[T](root: BinaryTree[T]): T =
|
||||
# inorder traversal of a binary tree
|
||||
# recursive iterators are not yet implemented, so this does not work in
|
||||
# the current compiler!
|
||||
|
|
@ -49,7 +49,7 @@ The following example shows a generic binary tree can be modelled:
|
|||
if root.ri != nil: yield inorder(root.ri)
|
||||
|
||||
var
|
||||
root: PBinaryTree[string] # instantiate a PBinaryTree with the type string
|
||||
root: BinaryTree[string] # instantiate a BinaryTree with the type string
|
||||
add(root, newNode("hallo")) # instantiates generic procs ``newNode`` and
|
||||
add(root, newNode("world")) # ``add``
|
||||
for str in inorder(root):
|
||||
|
|
@ -60,14 +60,14 @@ Is operator
|
|||
-----------
|
||||
|
||||
The ``is`` operator checks for type equivalence at compile time. It is
|
||||
therefore very useful for type specialization within generic code:
|
||||
therefore very useful for type specialization within generic code:
|
||||
|
||||
.. code-block:: nim
|
||||
type
|
||||
TTable[TKey, TValue] = object
|
||||
keys: seq[TKey]
|
||||
values: seq[TValue]
|
||||
when not (TKey is string): # nil value for strings used for optimization
|
||||
Table[Key, Value] = object
|
||||
keys: seq[Key]
|
||||
values: seq[Value]
|
||||
when not (Key is string): # nil value for strings used for optimization
|
||||
deletedKeys: seq[bool]
|
||||
|
||||
|
||||
|
|
@ -75,7 +75,7 @@ Type operator
|
|||
-------------
|
||||
|
||||
The ``type`` (in many other languages called `typeof`:idx:) operator can
|
||||
be used to get the type of an expression:
|
||||
be used to get the type of an expression:
|
||||
|
||||
.. code-block:: nim
|
||||
var x = 0
|
||||
|
|
@ -88,7 +88,7 @@ other interpretations:
|
|||
|
||||
.. code-block:: nim
|
||||
import strutils
|
||||
|
||||
|
||||
# strutils contains both a ``split`` proc and iterator, but since an
|
||||
# an iterator is the preferred interpretation, `y` has the type ``string``:
|
||||
var y: type("a b c".split)
|
||||
|
|
@ -98,7 +98,7 @@ Type Classes
|
|||
------------
|
||||
|
||||
A type class is a special pseudo-type that can be used to match against
|
||||
types in the context of overload resolution or the ``is`` operator.
|
||||
types in the context of overload resolution or the ``is`` operator.
|
||||
Nim supports the following built-in type classes:
|
||||
|
||||
================== ===================================================
|
||||
|
|
@ -116,7 +116,7 @@ type class matches
|
|||
``array`` any array type
|
||||
``set`` any set type
|
||||
``seq`` any seq type
|
||||
``auto`` any type
|
||||
``auto`` any type
|
||||
================== ===================================================
|
||||
|
||||
Furthermore, every generic type automatically creates a type class of the same
|
||||
|
|
@ -127,14 +127,14 @@ more complex type classes:
|
|||
|
||||
.. code-block:: nim
|
||||
# create a type class that will match all tuple and object types
|
||||
type TRecordType = tuple or object
|
||||
type RecordType = tuple or object
|
||||
|
||||
proc printFields(rec: TRecordType) =
|
||||
proc printFields(rec: RecordType) =
|
||||
for key, value in fieldPairs(rec):
|
||||
echo key, " = ", value
|
||||
|
||||
Procedures utilizing type classes in such manner are considered to be
|
||||
`implicitly generic`:idx:. They will be instantiated once for each unique
|
||||
`implicitly generic`:idx:. They will be instantiated once for each unique
|
||||
combination of param types used within the program.
|
||||
|
||||
Nim also allows for type classes and regular types to be specified
|
||||
|
|
@ -142,7 +142,7 @@ as `type constraints`:idx: of the generic type parameter:
|
|||
|
||||
.. code-block:: nim
|
||||
proc onlyIntOrString[T: int|string](x, y: T) = discard
|
||||
|
||||
|
||||
onlyIntOrString(450, 616) # valid
|
||||
onlyIntOrString(5.0, 0.0) # type mismatch
|
||||
onlyIntOrString("xy", 50) # invalid as 'T' cannot be both at the same time
|
||||
|
|
@ -152,7 +152,7 @@ exactly one concrete type. Here is an example taken directly from the system
|
|||
module to illustrate this:
|
||||
|
||||
.. code-block:: nim
|
||||
proc `==`*(x, y: tuple): bool =
|
||||
proc `==`*(x, y: tuple): bool =
|
||||
## requires `x` and `y` to be of the same tuple type
|
||||
## generic ``==`` operator for tuples that is lifted from the components
|
||||
## of `x` and `y`.
|
||||
|
|
@ -160,8 +160,8 @@ module to illustrate this:
|
|||
for a, b in fields(x, y):
|
||||
if a != b: result = false
|
||||
|
||||
Alternatively, the ``distinct`` type modifier can be applied to the type class
|
||||
to allow each param matching the type class to bind to a different type.
|
||||
Alternatively, the ``distinct`` type modifier can be applied to the type class
|
||||
to allow each param matching the type class to bind to a different type.
|
||||
|
||||
If a proc param doesn't have a type specified, Nim will use the
|
||||
``distinct auto`` type class (also known as ``any``):
|
||||
|
|
@ -175,11 +175,11 @@ type parameters of the matched generic type. They can be easily accessed using
|
|||
the dot syntax:
|
||||
|
||||
.. code-block:: nim
|
||||
type TMatrix[T, Rows, Columns] = object
|
||||
type Matrix[T, Rows, Columns] = object
|
||||
...
|
||||
|
||||
proc `[]`(m: TMatrix, row, col: int): TMatrix.T =
|
||||
m.data[col * high(TMatrix.Columns) + row]
|
||||
proc `[]`(m: Matrix, row, col: int): Matrix.T =
|
||||
m.data[col * high(Matrix.Columns) + row]
|
||||
|
||||
Alternatively, the `type` operator can be used over the proc params for similar
|
||||
effect when anonymous or distinct type classes are used.
|
||||
|
|
@ -189,13 +189,13 @@ type, this results in another more specific type class:
|
|||
|
||||
.. code-block:: nim
|
||||
seq[ref object] # Any sequence storing references to any object type
|
||||
|
||||
|
||||
type T1 = auto
|
||||
proc foo(s: seq[T1], e: T1)
|
||||
# seq[T1] is the same as just `seq`, but T1 will be allowed to bind
|
||||
# to a single type, while the signature is being matched
|
||||
|
||||
TMatrix[Ordinal] # Any TMatrix instantiation using integer values
|
||||
Matrix[Ordinal] # Any Matrix instantiation using integer values
|
||||
|
||||
As seen in the previous example, in such instantiations, it's not necessary to
|
||||
supply all type parameters of the generic type, because any missing ones will
|
||||
|
|
@ -203,34 +203,33 @@ be inferred to have the equivalent of the `any` type class and thus they will
|
|||
match anything without discrimination.
|
||||
|
||||
|
||||
User defined type classes
|
||||
-------------------------
|
||||
Concepts
|
||||
--------
|
||||
|
||||
**Note**: User defined type classes are still in development.
|
||||
**Note**: Concepts are still in development.
|
||||
|
||||
The user-defined type classes are available in two flavours - declarative and
|
||||
imperative. Both are used to specify an arbitrary set of requirements that the
|
||||
matched type must satisfy.
|
||||
Concepts, also known as "user-defined type classes", are used to specify an
|
||||
arbitrary set of requirements that the matched type must satisfy.
|
||||
|
||||
Declarative type classes are written in the following form:
|
||||
Concepts are written in the following form:
|
||||
|
||||
.. code-block:: nim
|
||||
type
|
||||
Comparable = generic x, y
|
||||
Comparable = concept x, y
|
||||
(x < y) is bool
|
||||
|
||||
Container[T] = generic c
|
||||
c.len is ordinal
|
||||
Container[T] = concept c
|
||||
c.len is Ordinal
|
||||
items(c) is iterator
|
||||
for value in c:
|
||||
type(value) is T
|
||||
|
||||
The type class will be matched if:
|
||||
The concept is a match if:
|
||||
|
||||
a) all of the expressions within the body can be compiled for the tested type
|
||||
b) all statically evaluatable boolean expressions in the body must be true
|
||||
|
||||
The identifiers following the `generic` keyword represent instances of the
|
||||
The identifiers following the ``concept`` keyword represent instances of the
|
||||
currently matched type. These instances can act both as variables of the type,
|
||||
when used in contexts where a value is expected, and as the type itself when
|
||||
used in contexts where a type is expected.
|
||||
|
|
@ -240,45 +239,21 @@ type signatures of the required operations, but since type inference and
|
|||
default parameters are still applied in the provided block, it's also possible
|
||||
to encode usage protocols that do not reveal implementation details.
|
||||
|
||||
As a special rule providing further convenience when writing type classes, any
|
||||
As a special rule providing further convenience when writing concepts, any
|
||||
type value appearing in a callable expression will be treated as a variable of
|
||||
the designated type for overload resolution purposes, unless the type value was
|
||||
passed in its explicit ``typedesc[T]`` form:
|
||||
|
||||
.. code-block:: nim
|
||||
type
|
||||
OutputStream = generic S
|
||||
write(var S, string)
|
||||
OutputStream = concept s
|
||||
write(var s, string)
|
||||
|
||||
Much like generics, the user defined type classes will be instantiated exactly
|
||||
once for each tested type and any static code included within them will also be
|
||||
Much like generics, concepts are instantiated exactly
|
||||
once for each tested type and any static code included within them is also
|
||||
executed once.
|
||||
|
||||
|
||||
Type inference with type classes
|
||||
--------------------------------
|
||||
|
||||
If a type class is used as the return type of a proc and it won't be bound to
|
||||
a concrete type by some of the proc params, Nim will infer the return type
|
||||
from the proc body. This is usually used with the ``auto`` type class:
|
||||
|
||||
.. code-block:: nim
|
||||
proc makePair(a, b): auto = (first: a, second: b)
|
||||
|
||||
The return type will be treated as an additional generic param and can be
|
||||
explicitly specified at call sites as any other generic param.
|
||||
|
||||
Future versions of Nim may also support overloading based on the return type
|
||||
of the overloads. In such settings, the expected result type at call sites may
|
||||
also influence the inferred return type.
|
||||
|
||||
..
|
||||
Likewise, if a type class is used in another position where Nim expects a
|
||||
concrete type (e.g. a variable declaration or a type coercion), Nim will try
|
||||
to infer the concrete type by applying the matching algorithm that also used
|
||||
in overload resolution.
|
||||
|
||||
|
||||
Symbol lookup in generics
|
||||
-------------------------
|
||||
|
||||
|
|
@ -292,22 +267,22 @@ at definition and the context at instantiation are considered:
|
|||
|
||||
.. code-block:: nim
|
||||
type
|
||||
TIndex = distinct int
|
||||
|
||||
proc `==` (a, b: TIndex): bool {.borrow.}
|
||||
|
||||
var a = (0, 0.TIndex)
|
||||
var b = (0, 0.TIndex)
|
||||
|
||||
Index = distinct int
|
||||
|
||||
proc `==` (a, b: Index): bool {.borrow.}
|
||||
|
||||
var a = (0, 0.Index)
|
||||
var b = (0, 0.Index)
|
||||
|
||||
echo a == b # works!
|
||||
|
||||
In the example the generic ``==`` for tuples (as defined in the system module)
|
||||
uses the ``==`` operators of the tuple's components. However, the ``==`` for
|
||||
the ``TIndex`` type is defined *after* the ``==`` for tuples; yet the example
|
||||
the ``Index`` type is defined *after* the ``==`` for tuples; yet the example
|
||||
compiles as the instantiation takes the currently defined symbols into account
|
||||
too.
|
||||
|
||||
A symbol can be forced to be open by a `mixin`:idx: declaration:
|
||||
A symbol can be forced to be open by a `mixin`:idx: declaration:
|
||||
|
||||
.. code-block:: nim
|
||||
proc create*[T](): ref T =
|
||||
|
|
@ -321,16 +296,16 @@ A symbol can be forced to be open by a `mixin`:idx: declaration:
|
|||
Bind statement
|
||||
--------------
|
||||
|
||||
The ``bind`` statement is the counterpart to the ``mixin`` statement. It
|
||||
The ``bind`` statement is the counterpart to the ``mixin`` statement. It
|
||||
can be used to explicitly declare identifiers that should be bound early (i.e.
|
||||
the identifiers should be looked up in the scope of the template/generic
|
||||
definition):
|
||||
|
||||
.. code-block:: nim
|
||||
# Module A
|
||||
var
|
||||
var
|
||||
lastId = 0
|
||||
|
||||
|
||||
template genId*: expr =
|
||||
bind lastId
|
||||
inc(lastId)
|
||||
|
|
@ -339,7 +314,7 @@ definition):
|
|||
.. code-block:: nim
|
||||
# Module B
|
||||
import A
|
||||
|
||||
|
||||
echo genId()
|
||||
|
||||
But a ``bind`` is rarely useful because symbol binding from the definition
|
||||
|
|
|
|||
|
|
@ -261,9 +261,9 @@ A character is not an Unicode character but a single byte. The reason for this
|
|||
is efficiency: for the overwhelming majority of use-cases, the resulting
|
||||
programs will still handle UTF-8 properly as UTF-8 was specially designed for
|
||||
this. Another reason is that Nim can thus support ``array[char, int]`` or
|
||||
``set[char]`` efficiently as many algorithms rely on this feature. The `TRune`
|
||||
``set[char]`` efficiently as many algorithms rely on this feature. The `Rune`
|
||||
type is used for Unicode characters, it can represent any Unicode character.
|
||||
``TRune`` is declared in the `unicode module <unicode.html>`_.
|
||||
``Rune`` is declared in the `unicode module <unicode.html>`_.
|
||||
|
||||
|
||||
Numerical constants
|
||||
|
|
@ -289,7 +289,7 @@ Numerical constants are of a single type and have the form::
|
|||
INT32_LIT = INT_LIT ['\''] ('i' | 'I') '32'
|
||||
INT64_LIT = INT_LIT ['\''] ('i' | 'I') '64'
|
||||
|
||||
UINT8_LIT = INT_LIT ['\''] ('u' | 'U')
|
||||
UINT_LIT = INT_LIT ['\''] ('u' | 'U')
|
||||
UINT8_LIT = INT_LIT ['\''] ('u' | 'U') '8'
|
||||
UINT16_LIT = INT_LIT ['\''] ('u' | 'U') '16'
|
||||
UINT32_LIT = INT_LIT ['\''] ('u' | 'U') '32'
|
||||
|
|
|
|||
|
|
@ -128,22 +128,22 @@ modules don't need to import a module's dependencies:
|
|||
|
||||
.. code-block:: nim
|
||||
# module B
|
||||
type TMyObject* = object
|
||||
type MyObject* = object
|
||||
|
||||
.. code-block:: nim
|
||||
# module A
|
||||
import B
|
||||
export B.TMyObject
|
||||
export B.MyObject
|
||||
|
||||
proc `$`*(x: TMyObject): string = "my object"
|
||||
proc `$`*(x: MyObject): string = "my object"
|
||||
|
||||
|
||||
.. code-block:: nim
|
||||
# module C
|
||||
import A
|
||||
|
||||
# B.TMyObject has been imported implicitly here:
|
||||
var x: TMyObject
|
||||
# B.MyObject has been imported implicitly here:
|
||||
var x: MyObject
|
||||
echo($x)
|
||||
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue