mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-04 20:17:42 +00:00
Markdown indented code blocks (#20473)
* Implement Markdown indented code blocks
Additional indentation of 4 spaces makes a block an "indented code block"
(monospaced text without syntax highlighting).
Also `::` RST syntax for code blocks is disabled.
So instead of
```rst
see::
Some code
```
the code block should be written as
```markdown
see:
Some code
```
* Migrate RST literal blocks :: to Markdown's ones
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
::
|
||||
|
||||
nim command [options] [projectfile] [arguments]
|
||||
|
||||
|
||||
@@ -314,14 +314,14 @@ To avoid accidental highlighting follow this rule in ``*.nim`` files:
|
||||
programming languages, including identifiers, in ``*.nim`` files.
|
||||
|
||||
For languages other than Nim add a role after final backtick,
|
||||
e.g. for C++ inline highlighting::
|
||||
e.g. for C++ inline highlighting:
|
||||
|
||||
`#include <stdio.h>`:cpp:
|
||||
`#include <stdio.h>`:cpp:
|
||||
|
||||
For a currently unsupported language add the `:code:` role,
|
||||
like for SQL in this example::
|
||||
like for SQL in this example:
|
||||
|
||||
`SELECT * FROM <table_name>;`:code:
|
||||
`SELECT * FROM <table_name>;`:code:
|
||||
|
||||
Highlight shell commands by ``:cmd:`` role; for command line options use
|
||||
``:option:`` role, e.g.: \`--docInternal\`:option:.
|
||||
@@ -335,17 +335,17 @@ To avoid accidental highlighting follow this rule in ``*.nim`` files:
|
||||
``\`` and a final \` would get escaped)
|
||||
|
||||
.. Note:: ``*.rst`` files have ``:literal:`` as their default role.
|
||||
So for them the rule above is only applicable if the ``:nim:`` role
|
||||
is set up manually as the default \[*]::
|
||||
So for them the rule above is only applicable if the ``:nim:`` role
|
||||
is set up manually as the default \[*]:
|
||||
|
||||
.. role:: nim(code)
|
||||
:language: nim
|
||||
.. default-role:: nim
|
||||
.. role:: nim(code)
|
||||
:language: nim
|
||||
.. default-role:: nim
|
||||
|
||||
The first 2 lines are for other RST implementations,
|
||||
including Github one.
|
||||
The first 2 lines are for other RST implementations,
|
||||
including Github one.
|
||||
|
||||
\[*] this is fulfilled when ``doc/rstcommon.rst`` is included.
|
||||
\[*] this is fulfilled when ``doc/rstcommon.rst`` is included.
|
||||
|
||||
Best practices
|
||||
==============
|
||||
@@ -489,9 +489,9 @@ General commit rules
|
||||
git diff --check --cached || exit $?
|
||||
```
|
||||
5. Describe your commit and use your common sense.
|
||||
Example commit message::
|
||||
Example commit message:
|
||||
|
||||
Fixes #123; refs #124
|
||||
Fixes #123; refs #124
|
||||
|
||||
indicates that issue ``#123`` is completely fixed (GitHub may automatically
|
||||
close it when the PR is committed), whereas issue ``#124`` is referenced
|
||||
@@ -581,11 +581,9 @@ Code reviews
|
||||
3. In addition, you can view GitHub-like diffs locally to identify what was changed
|
||||
within a code block using `diff-highlight`:cmd: or `diff-so-fancy`:cmd:, e.g.:
|
||||
|
||||
::
|
||||
|
||||
# put this in ~/.gitconfig:
|
||||
[core]
|
||||
pager = "diff-so-fancy | less -R" # or: use: `diff-highlight`
|
||||
# put this in ~/.gitconfig:
|
||||
[core]
|
||||
pager = "diff-so-fancy | less -R" # or: use: `diff-highlight`
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -358,58 +358,57 @@ Rewrite rules
|
||||
The current implementation follows strategy (2). This means that resources are
|
||||
destroyed at the scope exit.
|
||||
|
||||
::
|
||||
|
||||
var x: T; stmts
|
||||
--------------- (destroy-var)
|
||||
var x: T; try stmts
|
||||
finally: `=destroy`(x)
|
||||
var x: T; stmts
|
||||
--------------- (destroy-var)
|
||||
var x: T; try stmts
|
||||
finally: `=destroy`(x)
|
||||
|
||||
|
||||
g(f(...))
|
||||
------------------------ (nested-function-call)
|
||||
g(let tmp;
|
||||
bitwiseCopy tmp, f(...);
|
||||
tmp)
|
||||
finally: `=destroy`(tmp)
|
||||
g(f(...))
|
||||
------------------------ (nested-function-call)
|
||||
g(let tmp;
|
||||
bitwiseCopy tmp, f(...);
|
||||
tmp)
|
||||
finally: `=destroy`(tmp)
|
||||
|
||||
|
||||
x = f(...)
|
||||
------------------------ (function-sink)
|
||||
`=sink`(x, f(...))
|
||||
x = f(...)
|
||||
------------------------ (function-sink)
|
||||
`=sink`(x, f(...))
|
||||
|
||||
|
||||
x = lastReadOf z
|
||||
------------------ (move-optimization)
|
||||
`=sink`(x, z)
|
||||
wasMoved(z)
|
||||
x = lastReadOf z
|
||||
------------------ (move-optimization)
|
||||
`=sink`(x, z)
|
||||
wasMoved(z)
|
||||
|
||||
|
||||
v = v
|
||||
------------------ (self-assignment-removal)
|
||||
discard "nop"
|
||||
v = v
|
||||
------------------ (self-assignment-removal)
|
||||
discard "nop"
|
||||
|
||||
|
||||
x = y
|
||||
------------------ (copy)
|
||||
`=copy`(x, y)
|
||||
x = y
|
||||
------------------ (copy)
|
||||
`=copy`(x, y)
|
||||
|
||||
|
||||
f_sink(g())
|
||||
----------------------- (call-to-sink)
|
||||
f_sink(g())
|
||||
f_sink(g())
|
||||
----------------------- (call-to-sink)
|
||||
f_sink(g())
|
||||
|
||||
|
||||
f_sink(notLastReadOf y)
|
||||
-------------------------- (copy-to-sink)
|
||||
(let tmp; `=copy`(tmp, y);
|
||||
f_sink(tmp))
|
||||
f_sink(notLastReadOf y)
|
||||
-------------------------- (copy-to-sink)
|
||||
(let tmp; `=copy`(tmp, y);
|
||||
f_sink(tmp))
|
||||
|
||||
|
||||
f_sink(lastReadOf y)
|
||||
----------------------- (move-to-sink)
|
||||
f_sink(y)
|
||||
wasMoved(y)
|
||||
f_sink(lastReadOf y)
|
||||
----------------------- (move-to-sink)
|
||||
f_sink(y)
|
||||
wasMoved(y)
|
||||
|
||||
|
||||
Object and array construction
|
||||
|
||||
171
doc/docgen.md
171
doc/docgen.md
@@ -64,10 +64,11 @@ Example:
|
||||
age: int
|
||||
```
|
||||
|
||||
Outputs::
|
||||
Person* = object
|
||||
name: string
|
||||
age: int
|
||||
Outputs:
|
||||
|
||||
Person* = object
|
||||
name: string
|
||||
age: int
|
||||
|
||||
This type contains a description of a person
|
||||
|
||||
@@ -133,10 +134,11 @@ The `doc`:option: command:
|
||||
nim doc docgen_sample.nim
|
||||
```
|
||||
|
||||
Partial Output::
|
||||
...
|
||||
proc helloWorld(times: int) {.raises: [], tags: [].}
|
||||
...
|
||||
Partial Output:
|
||||
|
||||
...
|
||||
proc helloWorld(times: int) {.raises: [], tags: [].}
|
||||
...
|
||||
|
||||
The full output can be seen here: [docgen_sample.html](docgen_sample.html).
|
||||
It runs after semantic checking and includes pragmas attached implicitly by the
|
||||
@@ -179,22 +181,23 @@ The `jsondoc`:option: command:
|
||||
nim jsondoc docgen_sample.nim
|
||||
```
|
||||
|
||||
Output::
|
||||
{
|
||||
"orig": "docgen_sample.nim",
|
||||
"nimble": "",
|
||||
"moduleDescription": "This module is a sample",
|
||||
"entries": [
|
||||
{
|
||||
"name": "helloWorld",
|
||||
"type": "skProc",
|
||||
"line": 5,
|
||||
"col": 0,
|
||||
"description": "Takes an integer and outputs as many "hello world!"s",
|
||||
"code": "proc helloWorld(times: int) {.raises: [], tags: [].}"
|
||||
}
|
||||
]
|
||||
}
|
||||
Output:
|
||||
|
||||
{
|
||||
"orig": "docgen_sample.nim",
|
||||
"nimble": "",
|
||||
"moduleDescription": "This module is a sample",
|
||||
"entries": [
|
||||
{
|
||||
"name": "helloWorld",
|
||||
"type": "skProc",
|
||||
"line": 5,
|
||||
"col": 0,
|
||||
"description": "Takes an integer and outputs as many "hello world!"s",
|
||||
"code": "proc helloWorld(times: int) {.raises: [], tags: [].}"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Similarly to the old `doc`:option: command, the old `jsondoc`:option: command has been
|
||||
renamed to `jsondoc0`:option:.
|
||||
@@ -205,18 +208,19 @@ The `jsondoc0`:option: command:
|
||||
nim jsondoc0 docgen_sample.nim
|
||||
```
|
||||
|
||||
Output::
|
||||
[
|
||||
{
|
||||
"comment": "This module is a sample."
|
||||
},
|
||||
{
|
||||
"name": "helloWorld",
|
||||
"type": "skProc",
|
||||
"description": "Takes an integer and outputs as many "hello world!"s",
|
||||
"code": "proc helloWorld*(times: int)"
|
||||
}
|
||||
]
|
||||
Output:
|
||||
|
||||
[
|
||||
{
|
||||
"comment": "This module is a sample."
|
||||
},
|
||||
{
|
||||
"name": "helloWorld",
|
||||
"type": "skProc",
|
||||
"description": "Takes an integer and outputs as many "hello world!"s",
|
||||
"code": "proc helloWorld*(times: int)"
|
||||
}
|
||||
]
|
||||
|
||||
Note that the `jsondoc`:option: command outputs its JSON without pretty-printing it,
|
||||
while `jsondoc0`:option: outputs pretty-printed JSON.
|
||||
@@ -247,10 +251,13 @@ If you have a constant:
|
||||
|
||||
then it should be referenced in one of the 2 forms:
|
||||
|
||||
A. non-qualified (no symbol kind specification)::
|
||||
pi_
|
||||
B. qualified (with symbol kind specification)::
|
||||
`const pi`_
|
||||
A. non-qualified (no symbol kind specification):
|
||||
|
||||
pi_
|
||||
|
||||
B. qualified (with symbol kind specification):
|
||||
|
||||
`const pi`_
|
||||
|
||||
For routine kinds there are more options. Consider this definition:
|
||||
|
||||
@@ -262,52 +269,52 @@ Generally following syntax is allowed for referencing `foo`:
|
||||
|
||||
* short (without parameters):
|
||||
|
||||
A. non-qualified::
|
||||
A. non-qualified:
|
||||
|
||||
foo_
|
||||
foo_
|
||||
|
||||
B. qualified::
|
||||
B. qualified:
|
||||
|
||||
`proc foo`_
|
||||
`proc foo`_
|
||||
|
||||
* longer variants (with parameters):
|
||||
|
||||
A. non-qualified:
|
||||
|
||||
1) specifying parameters names::
|
||||
1) specifying parameters names:
|
||||
|
||||
`foo(a, b)`_
|
||||
`foo(a, b)`_
|
||||
|
||||
2) specifying parameters types::
|
||||
2) specifying parameters types:
|
||||
|
||||
`foo(int, float)`_
|
||||
`foo(int, float)`_
|
||||
|
||||
3) specifying both names and types::
|
||||
3) specifying both names and types:
|
||||
|
||||
`foo(a: int, b: float)`_
|
||||
`foo(a: int, b: float)`_
|
||||
|
||||
4) output parameter can also be specified if you wish::
|
||||
4) output parameter can also be specified if you wish:
|
||||
|
||||
`foo(a: int, b: float): string`_
|
||||
`foo(a: int, b: float): string`_
|
||||
|
||||
B. qualified: all 4 options above are valid.
|
||||
Particularly you can use the full format::
|
||||
Particularly you can use the full format:
|
||||
|
||||
`proc foo(a: int, b: float): string`_
|
||||
`proc foo(a: int, b: float): string`_
|
||||
|
||||
.. Tip:: Avoid cluttering your text with extraneous information by using
|
||||
one of shorter forms::
|
||||
one of shorter forms:
|
||||
|
||||
binarySearch_
|
||||
`binarySearch(a, key, cmp)`_
|
||||
binarySearch_
|
||||
`binarySearch(a, key, cmp)`_
|
||||
|
||||
Brevity is better for reading! If you use a short form and have an
|
||||
ambiguity problem (see below) then just add some additional info.
|
||||
|
||||
Symbol kind like `proc` can also be specified in the postfix form::
|
||||
Symbol kind like `proc` can also be specified in the postfix form:
|
||||
|
||||
`foo proc`_
|
||||
`walkDir(d: string) iterator`_
|
||||
`foo proc`_
|
||||
`walkDir(d: string) iterator`_
|
||||
|
||||
.. Warning:: An ambiguity in resolving documentation links may arise because of:
|
||||
|
||||
@@ -320,9 +327,9 @@ Symbol kind like `proc` can also be specified in the postfix form::
|
||||
`proc` and `template`. In this case they are split between their
|
||||
corresponding sections in output file. Qualified references are
|
||||
useful in this case -- just disambiguate by referring to these
|
||||
sections explicitly::
|
||||
sections explicitly:
|
||||
|
||||
See `foo proc`_ and `foo template`_.
|
||||
See `foo proc`_ and `foo template`_.
|
||||
|
||||
* because in Nim `proc` and `iterator` belong to different namespaces,
|
||||
so there can be a collision even if parameters are the same.
|
||||
@@ -334,9 +341,9 @@ Symbol kind like `proc` can also be specified in the postfix form::
|
||||
(while procs have higher priority than other Nim symbol kinds).
|
||||
|
||||
Generic parameters can also be used. All in all, this long form will be
|
||||
recognized fine::
|
||||
recognized fine:
|
||||
|
||||
`proc binarySearch*[T; K](a: openArray[T], key: K, cmp: proc(T, K)): int`_
|
||||
`proc binarySearch*[T; K](a: openArray[T], key: K, cmp: proc(T, K)): int`_
|
||||
|
||||
**Limitations**:
|
||||
|
||||
@@ -351,16 +358,16 @@ recognized fine::
|
||||
```
|
||||
|
||||
you cannot use names underlined by `~~` so it must be referenced with
|
||||
``cmp: proc(T, K)``. Hence these forms are valid::
|
||||
``cmp: proc(T, K)``. Hence these forms are valid:
|
||||
|
||||
`binarySearch(a: openArray[T], key: K, cmp: proc(T, K))`_
|
||||
`binarySearch(openArray[T], K, proc(T, K))`_
|
||||
`binarySearch(a, key, cmp)`_
|
||||
`binarySearch(a: openArray[T], key: K, cmp: proc(T, K))`_
|
||||
`binarySearch(openArray[T], K, proc(T, K))`_
|
||||
`binarySearch(a, key, cmp)`_
|
||||
2. Default values in routine parameters are not recognized, one needs to
|
||||
specify the type and/or name instead. E.g. for referencing `proc f(x = 7)`
|
||||
use one of the mentioned forms::
|
||||
use one of the mentioned forms:
|
||||
|
||||
`f(int)`_ or `f(x)`_ or `f(x: int)`_.
|
||||
`f(int)`_ or `f(x)`_ or `f(x: int)`_.
|
||||
3. Generic parameters must be given the same way as in the
|
||||
definition of referenced symbol.
|
||||
|
||||
@@ -376,27 +383,27 @@ recognized fine::
|
||||
func `[]`*[T](x: openArray[T]): T
|
||||
```
|
||||
|
||||
A short form works without additional backticks::
|
||||
A short form works without additional backticks:
|
||||
|
||||
`$`_
|
||||
`[]`_
|
||||
`$`_
|
||||
`[]`_
|
||||
|
||||
However for fully-qualified reference copy-pasting backticks (`) into other
|
||||
backticks will not work in our RST parser (because we use Markdown-like
|
||||
inline markup rules). You need either to delete backticks or keep
|
||||
them and escape with backslash \\::
|
||||
them and escape with backslash \\:
|
||||
|
||||
no backticks: `func $`_
|
||||
escaped: `func \`$\``_
|
||||
no backticks: `func [][T](x: openArray[T]): T`_
|
||||
escaped: `func \`[]\`[T](x: openArray[T]): T`_
|
||||
no backticks: `func $`_
|
||||
escaped: `func \`$\``_
|
||||
no backticks: `func [][T](x: openArray[T]): T`_
|
||||
escaped: `func \`[]\`[T](x: openArray[T]): T`_
|
||||
|
||||
.. Note:: Types that defined as `enum`, or `object`, or `tuple` can also be
|
||||
referenced with those names directly (instead of `type`)::
|
||||
referenced with those names directly (instead of `type`):
|
||||
|
||||
type CopyFlag = enum
|
||||
...
|
||||
## Ref. `CopyFlag enum`_
|
||||
type CopyFlag = enum
|
||||
...
|
||||
## Ref. `CopyFlag enum`_
|
||||
|
||||
Related Options
|
||||
===============
|
||||
|
||||
36
doc/drnim.md
36
doc/drnim.md
@@ -66,9 +66,9 @@ without additional annotations:
|
||||
```
|
||||
|
||||
This program contains a famous "index out of bounds" bug. DrNim
|
||||
detects it and produces the following error message::
|
||||
detects it and produces the following error message:
|
||||
|
||||
cannot prove: i <= len(a) + -1; counter example: i -> 0 a.len -> 0 [IndexCheck]
|
||||
cannot prove: i <= len(a) + -1; counter example: i -> 0 a.len -> 0 [IndexCheck]
|
||||
|
||||
In other words for `i == 0` and `a.len == 0` (for example!) there would be
|
||||
an index out of bounds error.
|
||||
@@ -146,9 +146,9 @@ Example: insertionSort
|
||||
Unfortunately, the invariants required to prove that this code is correct take more
|
||||
code than the imperative instructions. However, this effort can be compensated
|
||||
by the fact that the result needs very little testing. Be aware though that
|
||||
DrNim only proves that after `insertionSort` this condition holds::
|
||||
DrNim only proves that after `insertionSort` this condition holds:
|
||||
|
||||
forall(i in 1..<a.len, a[i-1] <= a[i])
|
||||
forall(i in 1..<a.len, a[i-1] <= a[i])
|
||||
|
||||
|
||||
This is required, but not sufficient to describe that a `sort` operation
|
||||
@@ -170,23 +170,23 @@ Syntax of propositions
|
||||
======================
|
||||
|
||||
The basic syntax is `ensures|requires|invariant: <prop>`.
|
||||
A `prop` is either a comparison or a compound::
|
||||
A `prop` is either a comparison or a compound:
|
||||
|
||||
prop = nim_bool_expression
|
||||
| prop 'and' prop
|
||||
| prop 'or' prop
|
||||
| prop '->' prop # implication
|
||||
| prop '<->' prop
|
||||
| 'not' prop
|
||||
| '(' prop ')' # you can group props via ()
|
||||
| forallProp
|
||||
| existsProp
|
||||
prop = nim_bool_expression
|
||||
| prop 'and' prop
|
||||
| prop 'or' prop
|
||||
| prop '->' prop # implication
|
||||
| prop '<->' prop
|
||||
| 'not' prop
|
||||
| '(' prop ')' # you can group props via ()
|
||||
| forallProp
|
||||
| existsProp
|
||||
|
||||
forallProp = 'forall' '(' quantifierList ',' prop ')'
|
||||
existsProp = 'exists' '(' quantifierList ',' prop ')'
|
||||
forallProp = 'forall' '(' quantifierList ',' prop ')'
|
||||
existsProp = 'exists' '(' quantifierList ',' prop ')'
|
||||
|
||||
quantifierList = quantifier (',' quantifier)*
|
||||
quantifier = <new identifier> 'in' nim_iteration_expression
|
||||
quantifierList = quantifier (',' quantifier)*
|
||||
quantifier = <new identifier> 'in' nim_iteration_expression
|
||||
|
||||
|
||||
`nim_iteration_expression` here is an ordinary expression of Nim code
|
||||
|
||||
269
doc/estp.md
269
doc/estp.md
@@ -70,138 +70,137 @@ the trace acts like an explanation; in traditional profilers you can only find
|
||||
expensive leaf functions easily but the *reason* why they are invoked
|
||||
often remains mysterious.
|
||||
|
||||
::
|
||||
total executions of each stack trace:
|
||||
Entry: 0/3391 Calls: 84/4160 = 2.0% [sum: 84; 84/4160 = 2.0%]
|
||||
newCrcFromRopeAux
|
||||
crcFromRope
|
||||
writeRopeIfNotEqual
|
||||
shouldRecompile
|
||||
writeModule
|
||||
myClose
|
||||
closePasses
|
||||
processModule
|
||||
CompileModule
|
||||
CompileProject
|
||||
CommandCompileToC
|
||||
MainCommand
|
||||
HandleCmdLine
|
||||
nim
|
||||
Entry: 1/3391 Calls: 46/4160 = 1.1% [sum: 130; 130/4160 = 3.1%]
|
||||
updateCrc32
|
||||
newCrcFromRopeAux
|
||||
crcFromRope
|
||||
writeRopeIfNotEqual
|
||||
shouldRecompile
|
||||
writeModule
|
||||
myClose
|
||||
closePasses
|
||||
processModule
|
||||
CompileModule
|
||||
CompileProject
|
||||
CommandCompileToC
|
||||
MainCommand
|
||||
HandleCmdLine
|
||||
nim
|
||||
Entry: 2/3391 Calls: 41/4160 = 0.99% [sum: 171; 171/4160 = 4.1%]
|
||||
updateCrc32
|
||||
updateCrc32
|
||||
newCrcFromRopeAux
|
||||
crcFromRope
|
||||
writeRopeIfNotEqual
|
||||
shouldRecompile
|
||||
writeModule
|
||||
myClose
|
||||
closePasses
|
||||
processModule
|
||||
CompileModule
|
||||
CompileProject
|
||||
CommandCompileToC
|
||||
MainCommand
|
||||
HandleCmdLine
|
||||
nim
|
||||
Entry: 3/3391 Calls: 41/4160 = 0.99% [sum: 212; 212/4160 = 5.1%]
|
||||
crcFromFile
|
||||
writeRopeIfNotEqual
|
||||
shouldRecompile
|
||||
writeModule
|
||||
myClose
|
||||
closePasses
|
||||
processModule
|
||||
CompileModule
|
||||
CompileProject
|
||||
CommandCompileToC
|
||||
MainCommand
|
||||
HandleCmdLine
|
||||
nim
|
||||
Entry: 4/3391 Calls: 41/4160 = 0.99% [sum: 253; 253/4160 = 6.1%]
|
||||
updateCrc32
|
||||
crcFromFile
|
||||
writeRopeIfNotEqual
|
||||
shouldRecompile
|
||||
writeModule
|
||||
myClose
|
||||
closePasses
|
||||
processModule
|
||||
CompileModule
|
||||
CompileProject
|
||||
CommandCompileToC
|
||||
MainCommand
|
||||
HandleCmdLine
|
||||
nim
|
||||
Entry: 5/3391 Calls: 32/4160 = 0.77% [sum: 285; 285/4160 = 6.9%]
|
||||
pop
|
||||
newCrcFromRopeAux
|
||||
crcFromRope
|
||||
writeRopeIfNotEqual
|
||||
shouldRecompile
|
||||
writeModule
|
||||
myClose
|
||||
closePasses
|
||||
processModule
|
||||
CompileModule
|
||||
CompileProject
|
||||
CommandCompileToC
|
||||
MainCommand
|
||||
HandleCmdLine
|
||||
nim
|
||||
Entry: 6/3391 Calls: 17/4160 = 0.41% [sum: 302; 302/4160 = 7.3%]
|
||||
doOperation
|
||||
forAllChildrenAux
|
||||
pop
|
||||
newCrcFromRopeAux
|
||||
crcFromRope
|
||||
writeRopeIfNotEqual
|
||||
shouldRecompile
|
||||
writeModule
|
||||
myClose
|
||||
closePasses
|
||||
processModule
|
||||
CompileModule
|
||||
CompileProject
|
||||
CommandCompileToC
|
||||
MainCommand
|
||||
HandleCmdLine
|
||||
...
|
||||
nim
|
||||
Entry: 7/3391 Calls: 14/4160 = 0.34% [sum: 316; 316/4160 = 7.6%]
|
||||
Contains
|
||||
isAccessible
|
||||
interiorAllocatedPtr
|
||||
gcMark
|
||||
markStackAndRegisters
|
||||
collectCTBody
|
||||
collectCT
|
||||
rawNewObj
|
||||
newObj
|
||||
newNode
|
||||
copyTree
|
||||
matchesAux
|
||||
matches
|
||||
resolveOverloads
|
||||
semOverloadedCall
|
||||
semOverloadedCallAnalyseEffects
|
||||
...
|
||||
CommandCompileToC
|
||||
MainCommand
|
||||
HandleCmdLine
|
||||
total executions of each stack trace:
|
||||
Entry: 0/3391 Calls: 84/4160 = 2.0% [sum: 84; 84/4160 = 2.0%]
|
||||
newCrcFromRopeAux
|
||||
crcFromRope
|
||||
writeRopeIfNotEqual
|
||||
shouldRecompile
|
||||
writeModule
|
||||
myClose
|
||||
closePasses
|
||||
processModule
|
||||
CompileModule
|
||||
CompileProject
|
||||
CommandCompileToC
|
||||
MainCommand
|
||||
HandleCmdLine
|
||||
nim
|
||||
Entry: 1/3391 Calls: 46/4160 = 1.1% [sum: 130; 130/4160 = 3.1%]
|
||||
updateCrc32
|
||||
newCrcFromRopeAux
|
||||
crcFromRope
|
||||
writeRopeIfNotEqual
|
||||
shouldRecompile
|
||||
writeModule
|
||||
myClose
|
||||
closePasses
|
||||
processModule
|
||||
CompileModule
|
||||
CompileProject
|
||||
CommandCompileToC
|
||||
MainCommand
|
||||
HandleCmdLine
|
||||
nim
|
||||
Entry: 2/3391 Calls: 41/4160 = 0.99% [sum: 171; 171/4160 = 4.1%]
|
||||
updateCrc32
|
||||
updateCrc32
|
||||
newCrcFromRopeAux
|
||||
crcFromRope
|
||||
writeRopeIfNotEqual
|
||||
shouldRecompile
|
||||
writeModule
|
||||
myClose
|
||||
closePasses
|
||||
processModule
|
||||
CompileModule
|
||||
CompileProject
|
||||
CommandCompileToC
|
||||
MainCommand
|
||||
HandleCmdLine
|
||||
nim
|
||||
Entry: 3/3391 Calls: 41/4160 = 0.99% [sum: 212; 212/4160 = 5.1%]
|
||||
crcFromFile
|
||||
writeRopeIfNotEqual
|
||||
shouldRecompile
|
||||
writeModule
|
||||
myClose
|
||||
closePasses
|
||||
processModule
|
||||
CompileModule
|
||||
CompileProject
|
||||
CommandCompileToC
|
||||
MainCommand
|
||||
HandleCmdLine
|
||||
nim
|
||||
Entry: 4/3391 Calls: 41/4160 = 0.99% [sum: 253; 253/4160 = 6.1%]
|
||||
updateCrc32
|
||||
crcFromFile
|
||||
writeRopeIfNotEqual
|
||||
shouldRecompile
|
||||
writeModule
|
||||
myClose
|
||||
closePasses
|
||||
processModule
|
||||
CompileModule
|
||||
CompileProject
|
||||
CommandCompileToC
|
||||
MainCommand
|
||||
HandleCmdLine
|
||||
nim
|
||||
Entry: 5/3391 Calls: 32/4160 = 0.77% [sum: 285; 285/4160 = 6.9%]
|
||||
pop
|
||||
newCrcFromRopeAux
|
||||
crcFromRope
|
||||
writeRopeIfNotEqual
|
||||
shouldRecompile
|
||||
writeModule
|
||||
myClose
|
||||
closePasses
|
||||
processModule
|
||||
CompileModule
|
||||
CompileProject
|
||||
CommandCompileToC
|
||||
MainCommand
|
||||
HandleCmdLine
|
||||
nim
|
||||
Entry: 6/3391 Calls: 17/4160 = 0.41% [sum: 302; 302/4160 = 7.3%]
|
||||
doOperation
|
||||
forAllChildrenAux
|
||||
pop
|
||||
newCrcFromRopeAux
|
||||
crcFromRope
|
||||
writeRopeIfNotEqual
|
||||
shouldRecompile
|
||||
writeModule
|
||||
myClose
|
||||
closePasses
|
||||
processModule
|
||||
CompileModule
|
||||
CompileProject
|
||||
CommandCompileToC
|
||||
MainCommand
|
||||
HandleCmdLine
|
||||
...
|
||||
nim
|
||||
Entry: 7/3391 Calls: 14/4160 = 0.34% [sum: 316; 316/4160 = 7.6%]
|
||||
Contains
|
||||
isAccessible
|
||||
interiorAllocatedPtr
|
||||
gcMark
|
||||
markStackAndRegisters
|
||||
collectCTBody
|
||||
collectCT
|
||||
rawNewObj
|
||||
newObj
|
||||
newNode
|
||||
copyTree
|
||||
matchesAux
|
||||
matches
|
||||
resolveOverloads
|
||||
semOverloadedCall
|
||||
semOverloadedCallAnalyseEffects
|
||||
...
|
||||
CommandCompileToC
|
||||
MainCommand
|
||||
HandleCmdLine
|
||||
|
||||
132
doc/filters.md
132
doc/filters.md
@@ -10,15 +10,15 @@ A `Source Code Filter (SCF)` transforms the input character stream to an in-mem
|
||||
output stream before parsing. A filter can be used to provide templating
|
||||
systems or preprocessors.
|
||||
|
||||
To use a filter for a source file the `#?` notation is used::
|
||||
To use a filter for a source file the `#?` notation is used:
|
||||
|
||||
#? stdtmpl(subsChar = '$', metaChar = '#')
|
||||
#proc generateXML(name, age: string): string =
|
||||
# result = ""
|
||||
<xml>
|
||||
<name>$name</name>
|
||||
<age>$age</age>
|
||||
</xml>
|
||||
#? stdtmpl(subsChar = '$', metaChar = '#')
|
||||
#proc generateXML(name, age: string): string =
|
||||
# result = ""
|
||||
<xml>
|
||||
<name>$name</name>
|
||||
<age>$age</age>
|
||||
</xml>
|
||||
|
||||
As the example shows, passing arguments to a filter can be done
|
||||
just like an ordinary procedure call with named or positional arguments. The
|
||||
@@ -50,15 +50,15 @@ In your `main.nim`:
|
||||
Pipe operator
|
||||
=============
|
||||
|
||||
Filters can be combined with the `|` pipe operator::
|
||||
Filters can be combined with the `|` pipe operator:
|
||||
|
||||
#? strip(startswith="<") | stdtmpl
|
||||
#proc generateXML(name, age: string): string =
|
||||
# result = ""
|
||||
<xml>
|
||||
<name>$name</name>
|
||||
<age>$age</age>
|
||||
</xml>
|
||||
#? strip(startswith="<") | stdtmpl
|
||||
#proc generateXML(name, age: string): string =
|
||||
# result = ""
|
||||
<xml>
|
||||
<name>$name</name>
|
||||
<age>$age</age>
|
||||
</xml>
|
||||
|
||||
|
||||
Available filters
|
||||
@@ -123,31 +123,31 @@ Parameters and their defaults:
|
||||
* `toString: string = "$"`
|
||||
: the operation that is applied to each expression
|
||||
|
||||
Example::
|
||||
Example:
|
||||
|
||||
#? stdtmpl | standard
|
||||
#proc generateHTMLPage(title, currentTab, content: string,
|
||||
# tabs: openArray[string]): string =
|
||||
# result = ""
|
||||
<head><title>$title</title></head>
|
||||
<body>
|
||||
<div id="menu">
|
||||
<ul>
|
||||
#for tab in items(tabs):
|
||||
#if currentTab == tab:
|
||||
<li><a id="selected"
|
||||
#else:
|
||||
<li><a
|
||||
#end if
|
||||
href="${tab}.html">$tab</a></li>
|
||||
#end for
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
$content
|
||||
A dollar: $$.
|
||||
</div>
|
||||
</body>
|
||||
#? stdtmpl | standard
|
||||
#proc generateHTMLPage(title, currentTab, content: string,
|
||||
# tabs: openArray[string]): string =
|
||||
# result = ""
|
||||
<head><title>$title</title></head>
|
||||
<body>
|
||||
<div id="menu">
|
||||
<ul>
|
||||
#for tab in items(tabs):
|
||||
#if currentTab == tab:
|
||||
<li><a id="selected"
|
||||
#else:
|
||||
<li><a
|
||||
#end if
|
||||
href="${tab}.html">$tab</a></li>
|
||||
#end for
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
$content
|
||||
A dollar: $$.
|
||||
</div>
|
||||
</body>
|
||||
|
||||
The filter transforms this into:
|
||||
|
||||
@@ -183,36 +183,36 @@ whitespace) is converted to a string literal that is added to `result`.
|
||||
The substitution character introduces a Nim expression *e* within the
|
||||
string literal. *e* is converted to a string with the *toString* operation
|
||||
which defaults to `$`. For strong type checking, set `toString` to the
|
||||
empty string. *e* must match this PEG pattern::
|
||||
empty string. *e* must match this PEG pattern:
|
||||
|
||||
e <- [a-zA-Z\128-\255][a-zA-Z0-9\128-\255_.]* / '{' x '}'
|
||||
x <- '{' x+ '}' / [^}]*
|
||||
e <- [a-zA-Z\128-\255][a-zA-Z0-9\128-\255_.]* / '{' x '}'
|
||||
x <- '{' x+ '}' / [^}]*
|
||||
|
||||
To produce a single substitution character it has to be doubled: `$$`
|
||||
produces `$`.
|
||||
|
||||
The template engine is quite flexible. It is easy to produce a procedure that
|
||||
writes the template code directly to a file::
|
||||
writes the template code directly to a file:
|
||||
|
||||
#? stdtmpl(emit="f.write") | standard
|
||||
#proc writeHTMLPage(f: File, title, currentTab, content: string,
|
||||
# tabs: openArray[string]) =
|
||||
<head><title>$title</title></head>
|
||||
<body>
|
||||
<div id="menu">
|
||||
<ul>
|
||||
#for tab in items(tabs):
|
||||
#if currentTab == tab:
|
||||
<li><a id="selected"
|
||||
#else:
|
||||
<li><a
|
||||
#end if
|
||||
href="${tab}.html" title = "$title - $tab">$tab</a></li>
|
||||
#end for
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
$content
|
||||
A dollar: $$.
|
||||
</div>
|
||||
</body>
|
||||
#? stdtmpl(emit="f.write") | standard
|
||||
#proc writeHTMLPage(f: File, title, currentTab, content: string,
|
||||
# tabs: openArray[string]) =
|
||||
<head><title>$title</title></head>
|
||||
<body>
|
||||
<div id="menu">
|
||||
<ul>
|
||||
#for tab in items(tabs):
|
||||
#if currentTab == tab:
|
||||
<li><a id="selected"
|
||||
#else:
|
||||
<li><a
|
||||
#end if
|
||||
href="${tab}.html" title = "$title - $tab">$tab</a></li>
|
||||
#end for
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
$content
|
||||
A dollar: $$.
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -36,13 +36,17 @@ 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 invocations are::
|
||||
The general idetools invocations are:
|
||||
|
||||
nim idetools --track:FILE,LINE,COL <switches> proj.nim
|
||||
```cmd
|
||||
nim idetools --track:FILE,LINE,COL <switches> proj.nim
|
||||
```
|
||||
|
||||
Or::
|
||||
Or:
|
||||
|
||||
nim idetools --trackDirty:DIRTY_FILE,FILE,LINE,COL <switches> proj.nim
|
||||
```cmd
|
||||
nim idetools --trackDirty:DIRTY_FILE,FILE,LINE,COL <switches> proj.nim
|
||||
```
|
||||
|
||||
`proj.nim`
|
||||
: This is the main *project* filename. Most of the time you will
|
||||
@@ -178,14 +182,18 @@ results of the compilation, and subsequent queries should be fast
|
||||
in the millisecond range, thus being responsive enough for IDEs.
|
||||
|
||||
If you want to start the server using stdin/stdout as communication
|
||||
you need to type::
|
||||
you need to type:
|
||||
|
||||
nim serve --server.type:stdin proj.nim
|
||||
```cmd
|
||||
nim serve --server.type:stdin proj.nim
|
||||
```
|
||||
|
||||
If you want to start the server using tcp and a port, you need to type::
|
||||
If you want to start the server using tcp and a port, you need to type:
|
||||
|
||||
nim serve --server.type:tcp --server.port:6000 \
|
||||
```cmd
|
||||
nim serve --server.type:tcp --server.port:6000 \
|
||||
--server.address:hostname proj.nim
|
||||
```
|
||||
|
||||
In both cases the server will start up and await further commands.
|
||||
The syntax of the commands you can now send to the server is
|
||||
@@ -542,10 +550,12 @@ Running the test suite
|
||||
|
||||
At the moment idetools support is still in development so the test
|
||||
suite is not integrated with the main test suite and you have to
|
||||
run it manually. First you have to compile the tester::
|
||||
run it manually. First you have to compile the tester:
|
||||
|
||||
$ cd my/nim/checkout/tests
|
||||
$ nim c testament/caasdriver.nim
|
||||
```cmd
|
||||
$ cd my/nim/checkout/tests
|
||||
$ nim c testament/caasdriver.nim
|
||||
```
|
||||
|
||||
Running the `caasdriver` without parameters will attempt to process
|
||||
all the test cases in all three operation modes. If a test succeeds
|
||||
@@ -567,9 +577,11 @@ If you don't want to run all the test case files you can pass any
|
||||
substring as a parameter to `caasdriver`. Only files matching the
|
||||
passed substring will be run. The filtering doesn't use any globbing
|
||||
metacharacters, it's a plain match. For example, to run only
|
||||
`*-compile*.txt` tests in verbose mode::
|
||||
`*-compile*.txt` tests in verbose mode:
|
||||
|
||||
./caasdriver verbose -compile
|
||||
```cmd
|
||||
./caasdriver verbose -compile
|
||||
```
|
||||
|
||||
|
||||
Test case file format
|
||||
|
||||
@@ -593,14 +593,14 @@ Integer literals
|
||||
In Nim, there is a redundant way to specify the type of an
|
||||
integer literal. First, it should be unsurprising that every
|
||||
node has a node kind. The node of an integer literal can be any of the
|
||||
following values::
|
||||
following values:
|
||||
|
||||
nkIntLit, nkInt8Lit, nkInt16Lit, nkInt32Lit, nkInt64Lit,
|
||||
nkUIntLit, nkUInt8Lit, nkUInt16Lit, nkUInt32Lit, nkUInt64Lit
|
||||
|
||||
On top of that, there is also the `typ` field for the type. The
|
||||
kind of the `typ` field can be one of the following ones, and it
|
||||
should be matching the literal kind::
|
||||
should be matching the literal kind:
|
||||
|
||||
tyInt, tyInt8, tyInt16, tyInt32, tyInt64, tyUInt, tyUInt8,
|
||||
tyUInt16, tyUInt32, tyUInt64
|
||||
@@ -656,7 +656,6 @@ pointing back to the integer literal node in the ast containing the
|
||||
integer value. These are the properties that hold true for integer
|
||||
literal types.
|
||||
|
||||
::
|
||||
n.kind == nkIntLit
|
||||
n.typ.kind == tyInt
|
||||
n.typ.n == n
|
||||
|
||||
146
doc/manual.md
146
doc/manual.md
@@ -47,16 +47,16 @@ is not ambiguous.
|
||||
|
||||
Non-terminals start with a lowercase letter, abstract terminal symbols are in
|
||||
UPPERCASE. Verbatim terminal symbols (including keywords) are quoted
|
||||
with `'`. An example::
|
||||
with `'`. An example:
|
||||
|
||||
ifStmt = 'if' expr ':' stmts ('elif' expr ':' stmts)* ('else' stmts)?
|
||||
ifStmt = 'if' expr ':' stmts ('elif' expr ':' stmts)* ('else' stmts)?
|
||||
|
||||
The binary `^*` operator is used as a shorthand for 0 or more occurrences
|
||||
separated by its second argument; likewise `^+` means 1 or more
|
||||
occurrences: `a ^+ b` is short for `a (b a)*`
|
||||
and `a ^* b` is short for `(a (b a)*)?`. Example::
|
||||
and `a ^* b` is short for `(a (b a)*)?`. Example:
|
||||
|
||||
arrayConstructor = '[' expr ^* ',' ']'
|
||||
arrayConstructor = '[' expr ^* ',' ']'
|
||||
|
||||
Other parts of Nim, like scoping rules or runtime semantics, are
|
||||
described informally.
|
||||
@@ -190,16 +190,16 @@ is another pseudo terminal that describes the *action* of popping a value
|
||||
from the stack, `IND{>}` then implies to push onto the stack.
|
||||
|
||||
With this notation we can now easily define the core of the grammar: A block of
|
||||
statements (simplified example)::
|
||||
statements (simplified example):
|
||||
|
||||
ifStmt = 'if' expr ':' stmt
|
||||
(IND{=} 'elif' expr ':' stmt)*
|
||||
(IND{=} 'else' ':' stmt)?
|
||||
ifStmt = 'if' expr ':' stmt
|
||||
(IND{=} 'elif' expr ':' stmt)*
|
||||
(IND{=} 'else' ':' stmt)?
|
||||
|
||||
simpleStmt = ifStmt / ...
|
||||
simpleStmt = ifStmt / ...
|
||||
|
||||
stmt = IND{>} stmt ^+ IND{=} DED # list of statements
|
||||
/ simpleStmt # or a simple statement
|
||||
stmt = IND{>} stmt ^+ IND{=} DED # list of statements
|
||||
/ simpleStmt # or a simple statement
|
||||
|
||||
|
||||
|
||||
@@ -409,9 +409,9 @@ ending of the string literal is defined by the pattern `"""[^"]`, so this:
|
||||
""""long string within quotes""""
|
||||
```
|
||||
|
||||
Produces::
|
||||
Produces:
|
||||
|
||||
"long string within quotes"
|
||||
"long string within quotes"
|
||||
|
||||
|
||||
Raw string literals
|
||||
@@ -434,9 +434,9 @@ To produce a single `"` within a raw string literal, it has to be doubled:
|
||||
r"a""b"
|
||||
```
|
||||
|
||||
Produces::
|
||||
Produces:
|
||||
|
||||
a"b
|
||||
a"b
|
||||
|
||||
`r""""` is not possible with this notation, because the three leading
|
||||
quotes introduce a triple quoted string literal. `r"""` is the same
|
||||
@@ -513,46 +513,46 @@ See also [custom numeric literals].
|
||||
Numeric literals
|
||||
----------------
|
||||
|
||||
Numeric literals have the form::
|
||||
Numeric literals have the form:
|
||||
|
||||
hexdigit = digit | 'A'..'F' | 'a'..'f'
|
||||
octdigit = '0'..'7'
|
||||
bindigit = '0'..'1'
|
||||
unary_minus = '-' # See the section about unary minus
|
||||
HEX_LIT = unary_minus? '0' ('x' | 'X' ) hexdigit ( ['_'] hexdigit )*
|
||||
DEC_LIT = unary_minus? digit ( ['_'] digit )*
|
||||
OCT_LIT = unary_minus? '0' 'o' octdigit ( ['_'] octdigit )*
|
||||
BIN_LIT = unary_minus? '0' ('b' | 'B' ) bindigit ( ['_'] bindigit )*
|
||||
hexdigit = digit | 'A'..'F' | 'a'..'f'
|
||||
octdigit = '0'..'7'
|
||||
bindigit = '0'..'1'
|
||||
unary_minus = '-' # See the section about unary minus
|
||||
HEX_LIT = unary_minus? '0' ('x' | 'X' ) hexdigit ( ['_'] hexdigit )*
|
||||
DEC_LIT = unary_minus? digit ( ['_'] digit )*
|
||||
OCT_LIT = unary_minus? '0' 'o' octdigit ( ['_'] octdigit )*
|
||||
BIN_LIT = unary_minus? '0' ('b' | 'B' ) bindigit ( ['_'] bindigit )*
|
||||
|
||||
INT_LIT = HEX_LIT
|
||||
| DEC_LIT
|
||||
| OCT_LIT
|
||||
| BIN_LIT
|
||||
INT_LIT = HEX_LIT
|
||||
| DEC_LIT
|
||||
| OCT_LIT
|
||||
| BIN_LIT
|
||||
|
||||
INT8_LIT = INT_LIT ['\''] ('i' | 'I') '8'
|
||||
INT16_LIT = INT_LIT ['\''] ('i' | 'I') '16'
|
||||
INT32_LIT = INT_LIT ['\''] ('i' | 'I') '32'
|
||||
INT64_LIT = INT_LIT ['\''] ('i' | 'I') '64'
|
||||
INT8_LIT = INT_LIT ['\''] ('i' | 'I') '8'
|
||||
INT16_LIT = INT_LIT ['\''] ('i' | 'I') '16'
|
||||
INT32_LIT = INT_LIT ['\''] ('i' | 'I') '32'
|
||||
INT64_LIT = INT_LIT ['\''] ('i' | 'I') '64'
|
||||
|
||||
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'
|
||||
UINT64_LIT = INT_LIT ['\''] ('u' | 'U') '64'
|
||||
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'
|
||||
UINT64_LIT = INT_LIT ['\''] ('u' | 'U') '64'
|
||||
|
||||
exponent = ('e' | 'E' ) ['+' | '-'] digit ( ['_'] digit )*
|
||||
FLOAT_LIT = unary_minus? digit (['_'] digit)* (('.' digit (['_'] digit)* [exponent]) |exponent)
|
||||
FLOAT32_SUFFIX = ('f' | 'F') ['32']
|
||||
FLOAT32_LIT = HEX_LIT '\'' FLOAT32_SUFFIX
|
||||
| (FLOAT_LIT | DEC_LIT | OCT_LIT | BIN_LIT) ['\''] FLOAT32_SUFFIX
|
||||
FLOAT64_SUFFIX = ( ('f' | 'F') '64' ) | 'd' | 'D'
|
||||
FLOAT64_LIT = HEX_LIT '\'' FLOAT64_SUFFIX
|
||||
| (FLOAT_LIT | DEC_LIT | OCT_LIT | BIN_LIT) ['\''] FLOAT64_SUFFIX
|
||||
exponent = ('e' | 'E' ) ['+' | '-'] digit ( ['_'] digit )*
|
||||
FLOAT_LIT = unary_minus? digit (['_'] digit)* (('.' digit (['_'] digit)* [exponent]) |exponent)
|
||||
FLOAT32_SUFFIX = ('f' | 'F') ['32']
|
||||
FLOAT32_LIT = HEX_LIT '\'' FLOAT32_SUFFIX
|
||||
| (FLOAT_LIT | DEC_LIT | OCT_LIT | BIN_LIT) ['\''] FLOAT32_SUFFIX
|
||||
FLOAT64_SUFFIX = ( ('f' | 'F') '64' ) | 'd' | 'D'
|
||||
FLOAT64_LIT = HEX_LIT '\'' FLOAT64_SUFFIX
|
||||
| (FLOAT_LIT | DEC_LIT | OCT_LIT | BIN_LIT) ['\''] FLOAT64_SUFFIX
|
||||
|
||||
CUSTOM_NUMERIC_LIT = (FLOAT_LIT | INT_LIT) '\'' CUSTOM_NUMERIC_SUFFIX
|
||||
CUSTOM_NUMERIC_LIT = (FLOAT_LIT | INT_LIT) '\'' CUSTOM_NUMERIC_SUFFIX
|
||||
|
||||
# CUSTOM_NUMERIC_SUFFIX is any Nim identifier that is not
|
||||
# a pre-defined type suffix.
|
||||
# CUSTOM_NUMERIC_SUFFIX is any Nim identifier that is not
|
||||
# a pre-defined type suffix.
|
||||
|
||||
|
||||
As can be seen in the productions, numeric literals can contain underscores
|
||||
@@ -674,7 +674,7 @@ Operators
|
||||
---------
|
||||
|
||||
Nim allows user defined operators. An operator is any combination of the
|
||||
following characters::
|
||||
following characters:
|
||||
|
||||
= + - * / < >
|
||||
@ $ ~ & % |
|
||||
@@ -698,10 +698,10 @@ as `a(not b)`, not as `(a) not (b)`.
|
||||
Unicode Operators
|
||||
-----------------
|
||||
|
||||
These Unicode operators are also parsed as operators::
|
||||
These Unicode operators are also parsed as operators:
|
||||
|
||||
∙ ∘ × ★ ⊗ ⊘ ⊙ ⊛ ⊠ ⊡ ∩ ∧ ⊓ # same priority as * (multiplication)
|
||||
± ⊕ ⊖ ⊞ ⊟ ∪ ∨ ⊔ # same priority as + (addition)
|
||||
∙ ∘ × ★ ⊗ ⊘ ⊙ ⊛ ⊠ ⊡ ∩ ∧ ⊓ # same priority as * (multiplication)
|
||||
± ⊕ ⊖ ⊞ ⊟ ∪ ∨ ⊔ # same priority as + (addition)
|
||||
|
||||
|
||||
Unicode operators can be combined with non-Unicode operator
|
||||
@@ -714,7 +714,7 @@ No Unicode normalization step is performed.
|
||||
Other tokens
|
||||
------------
|
||||
|
||||
The following strings denote other tokens::
|
||||
The following strings denote other tokens:
|
||||
|
||||
` ( ) { } [ ] , ; [. .] {. .} (. .) [:
|
||||
|
||||
@@ -1207,9 +1207,11 @@ The boolean type is named `bool`:idx: in Nim and can be one of the two
|
||||
pre-defined values `true` and `false`. Conditions in `while`,
|
||||
`if`, `elif`, `when`-statements need to be of type `bool`.
|
||||
|
||||
This condition holds::
|
||||
This condition holds:
|
||||
|
||||
```nim
|
||||
ord(false) == 0 and ord(true) == 1
|
||||
```
|
||||
|
||||
The operators `not, and, or, xor, <, <=, >, >=, !=, ==` are defined
|
||||
for the bool type. The `and` and `or` operators perform short-cut
|
||||
@@ -1248,8 +1250,9 @@ specified. The values are ordered. Example:
|
||||
```
|
||||
|
||||
|
||||
Now the following holds::
|
||||
Now the following holds:
|
||||
|
||||
```nim
|
||||
ord(north) == 0
|
||||
ord(east) == 1
|
||||
ord(south) == 2
|
||||
@@ -1257,6 +1260,7 @@ Now the following holds::
|
||||
|
||||
# Also allowed:
|
||||
ord(Direction.west) == 3
|
||||
```
|
||||
|
||||
The implied order is: north < east < south < west. The comparison operators can be used
|
||||
with enumeration types. Instead of `north` etc., the enum value can also
|
||||
@@ -2568,8 +2572,9 @@ literal match and that is better than a generic match etc. In the following,
|
||||
for the routine `p`.
|
||||
|
||||
A routine `p` matches better than a routine `q` if the following
|
||||
algorithm returns true::
|
||||
algorithm returns true:
|
||||
|
||||
```nim
|
||||
for each matching category m in ["exact match", "literal match",
|
||||
"generic match", "subtype match",
|
||||
"integral match", "conversion match"]:
|
||||
@@ -2579,6 +2584,7 @@ algorithm returns true::
|
||||
else:
|
||||
return false
|
||||
return "ambiguous"
|
||||
```
|
||||
|
||||
|
||||
Some examples:
|
||||
@@ -4061,19 +4067,19 @@ Nonoverloadable builtins
|
||||
------------------------
|
||||
|
||||
The following built-in procs cannot be overloaded for reasons of implementation
|
||||
simplicity (they require specialized semantic checking)::
|
||||
simplicity (they require specialized semantic checking):
|
||||
|
||||
declared, defined, definedInScope, compiles, sizeof,
|
||||
is, shallowCopy, getAst, astToStr, spawn, procCall
|
||||
declared, defined, definedInScope, compiles, sizeof,
|
||||
is, shallowCopy, getAst, astToStr, spawn, procCall
|
||||
|
||||
Thus, they act more like keywords than like ordinary identifiers; unlike a
|
||||
keyword however, a redefinition may `shadow`:idx: the definition in
|
||||
the [system](system.html) module.
|
||||
From this list the following should not be written in dot
|
||||
notation `x.f` since `x` cannot be type-checked before it gets passed
|
||||
to `f`::
|
||||
to `f`:
|
||||
|
||||
declared, defined, definedInScope, compiles, getAst, astToStr
|
||||
declared, defined, definedInScope, compiles, getAst, astToStr
|
||||
|
||||
|
||||
Var parameters
|
||||
@@ -8291,16 +8297,16 @@ The `dynlib` import mechanism supports a versioning scheme:
|
||||
importc, dynlib: "libtcl(|8.5|8.4|8.3).so.(1|0)".}
|
||||
```
|
||||
|
||||
At runtime, the dynamic library is searched for (in this order)::
|
||||
At runtime, the dynamic library is searched for (in this order):
|
||||
|
||||
libtcl.so.1
|
||||
libtcl.so.0
|
||||
libtcl8.5.so.1
|
||||
libtcl8.5.so.0
|
||||
libtcl8.4.so.1
|
||||
libtcl8.4.so.0
|
||||
libtcl8.3.so.1
|
||||
libtcl8.3.so.0
|
||||
libtcl.so.1
|
||||
libtcl.so.0
|
||||
libtcl8.5.so.1
|
||||
libtcl8.5.so.0
|
||||
libtcl8.4.so.1
|
||||
libtcl8.4.so.0
|
||||
libtcl8.3.so.1
|
||||
libtcl8.3.so.0
|
||||
|
||||
The `dynlib` pragma supports not only constant strings as an argument but also
|
||||
string expressions in general:
|
||||
|
||||
@@ -790,9 +790,9 @@ be part of a single graph.
|
||||
Assignments like `a = b` "connect" two variables, both variables end up in the
|
||||
same graph `{a, b} = G(a) = G(b)`. Unfortunately, the pattern to look for is
|
||||
much more complex than that and can involve multiple assignment targets
|
||||
and sources::
|
||||
and sources:
|
||||
|
||||
f(x, y) = g(a, b)
|
||||
f(x, y) = g(a, b)
|
||||
|
||||
connects `x` and `y` to `a` and `b`: `G(x) = G(y) = G(a) = G(b) = {x, y, a, b}`.
|
||||
A type based alias analysis rules out some of these combinations, for example
|
||||
@@ -1586,16 +1586,16 @@ all the arguments, but also the matched operators in reverse polish notation:
|
||||
```
|
||||
|
||||
This passes the expression `x + y * z - x` to the `optM` macro as
|
||||
an `nnkArgList` node containing::
|
||||
an `nnkArgList` node containing:
|
||||
|
||||
Arglist
|
||||
Sym "x"
|
||||
Sym "y"
|
||||
Sym "z"
|
||||
Sym "*"
|
||||
Sym "+"
|
||||
Sym "x"
|
||||
Sym "-"
|
||||
Arglist
|
||||
Sym "x"
|
||||
Sym "y"
|
||||
Sym "z"
|
||||
Sym "*"
|
||||
Sym "+"
|
||||
Sym "x"
|
||||
Sym "-"
|
||||
|
||||
(This is the reverse polish notation of `x + y * z - x`.)
|
||||
|
||||
|
||||
@@ -22,8 +22,9 @@ Usage (to convert Markdown into HTML):
|
||||
nim md2html markdown_rst.md
|
||||
```
|
||||
|
||||
Output::
|
||||
You're reading it!
|
||||
Output:
|
||||
|
||||
You're reading it!
|
||||
|
||||
The `md2tex`:option: command is invoked identically to `md2html`:option:,
|
||||
but outputs a ``.tex`` file instead of ``.html``.
|
||||
@@ -132,10 +133,10 @@ Additional Nim-specific features
|
||||
* ``:idx:`` role for \`interpreted text\` to include the link to this
|
||||
text into an index (example: [Nim index]).
|
||||
* double slash `//` in option lists serves as a prefix for any option that
|
||||
starts from a word (without any leading symbols like `-`, `--`, `/`)::
|
||||
starts from a word (without any leading symbols like `-`, `--`, `/`):
|
||||
|
||||
//compile compile the project
|
||||
//doc generate documentation
|
||||
//compile compile the project
|
||||
//doc generate documentation
|
||||
|
||||
Here the dummy `//` will disappear, while options `compile`:option:
|
||||
and `doc`:option: will be left in the final document.
|
||||
@@ -152,11 +153,11 @@ Optional additional features, by default turned on:
|
||||
* Markdown tables
|
||||
* Markdown code blocks. For them the same additional arguments as for RST
|
||||
code blocks can be provided (e.g. `test` or `number-lines`) but with
|
||||
a one-line syntax like this::
|
||||
a one-line syntax like this:
|
||||
|
||||
```nim test number-lines=10
|
||||
echo "ok"
|
||||
```
|
||||
```nim test number-lines=10
|
||||
echo "ok"
|
||||
```
|
||||
* Markdown links
|
||||
* Markdown headlines
|
||||
* Markdown block quotes
|
||||
@@ -189,11 +190,11 @@ This parser has 2 modes for inline markup:
|
||||
does escape so that we can always input a single backtick ` in
|
||||
inline code. However that makes impossible to input code with
|
||||
``\`` at the end in *single* backticks, one must use *double*
|
||||
backticks::
|
||||
backticks:
|
||||
|
||||
`\` -- WRONG
|
||||
``\`` -- GOOD
|
||||
So single backticks can always be input: `\`` will turn to ` code
|
||||
`\` -- WRONG
|
||||
``\`` -- GOOD
|
||||
So single backticks can always be input: `\`` will turn to ` code
|
||||
|
||||
.. Attention::
|
||||
We don't support some obviously poor design choices of Markdown (or RST).
|
||||
@@ -204,11 +205,9 @@ This parser has 2 modes for inline markup:
|
||||
- interpretation of Markdown block quotes is also slightly different,
|
||||
e.g. case
|
||||
|
||||
::
|
||||
|
||||
>>> foo
|
||||
> bar
|
||||
>>baz
|
||||
>>> foo
|
||||
> bar
|
||||
>>baz
|
||||
|
||||
is a single 3rd-level quote `foo bar baz` in original Markdown, while
|
||||
in Nim we naturally see it as 3rd-level quote `foo` + 1st level `bar` +
|
||||
|
||||
32
doc/nimc.md
32
doc/nimc.md
@@ -241,13 +241,13 @@ found an ambiguity error is produced.
|
||||
|
||||
However before the PATH is used the current directory is checked for the
|
||||
file's existence. So if PATH contains ``$lib`` and ``$lib/bar`` and the
|
||||
directory structure looks like this::
|
||||
directory structure looks like this:
|
||||
|
||||
$lib/x.nim
|
||||
$lib/bar/x.nim
|
||||
foo/x.nim
|
||||
foo/main.nim
|
||||
other.nim
|
||||
$lib/x.nim
|
||||
$lib/bar/x.nim
|
||||
foo/x.nim
|
||||
foo/main.nim
|
||||
other.nim
|
||||
|
||||
And `main` imports `x`, `foo/x` is imported. If `other` imports `x`
|
||||
then both ``$lib/x.nim`` and ``$lib/bar/x.nim`` match but ``$lib/x.nim`` is used
|
||||
@@ -319,11 +319,11 @@ Another way is to make Nim invoke a cross compiler toolchain:
|
||||
For cross compilation, the compiler invokes a C compiler named
|
||||
like `$cpu.$os.$cc` (for example arm.linux.gcc) and the configuration
|
||||
system is used to provide meaningful defaults. For example for `ARM` your
|
||||
configuration file should contain something like::
|
||||
configuration file should contain something like:
|
||||
|
||||
arm.linux.gcc.path = "/usr/bin"
|
||||
arm.linux.gcc.exe = "arm-linux-gcc"
|
||||
arm.linux.gcc.linkerexe = "arm-linux-gcc"
|
||||
arm.linux.gcc.path = "/usr/bin"
|
||||
arm.linux.gcc.exe = "arm-linux-gcc"
|
||||
arm.linux.gcc.linkerexe = "arm-linux-gcc"
|
||||
|
||||
Cross-compilation for Windows
|
||||
=============================
|
||||
@@ -435,13 +435,13 @@ and `passL`:option: command line switches to something like:
|
||||
--passL="-specs=$DEVKITPRO/libnx/switch.specs -L$DEVKITPRO/libnx/lib -lnx"
|
||||
```
|
||||
|
||||
or setup a ``nim.cfg`` file like so::
|
||||
or setup a ``nim.cfg`` file like so:
|
||||
|
||||
#nim.cfg
|
||||
--mm:orc
|
||||
--d:nimAllocPagesViaMalloc
|
||||
--passC="-I$DEVKITPRO/libnx/include"
|
||||
--passL="-specs=$DEVKITPRO/libnx/switch.specs -L$DEVKITPRO/libnx/lib -lnx"
|
||||
#nim.cfg
|
||||
--mm:orc
|
||||
--d:nimAllocPagesViaMalloc
|
||||
--passC="-I$DEVKITPRO/libnx/include"
|
||||
--passL="-specs=$DEVKITPRO/libnx/switch.specs -L$DEVKITPRO/libnx/lib -lnx"
|
||||
|
||||
The devkitPro setup must be the same as the default with their new installer
|
||||
[here for Mac/Linux](https://github.com/devkitPro/pacman/releases) or
|
||||
|
||||
@@ -28,21 +28,28 @@ system by this day and age, your project is already in big trouble.
|
||||
Installation
|
||||
------------
|
||||
|
||||
Nimfix is part of the compiler distribution. Compile via::
|
||||
Nimfix is part of the compiler distribution. Compile via:
|
||||
|
||||
```cmd
|
||||
nim c compiler/nimfix/nimfix.nim
|
||||
mv compiler/nimfix/nimfix bin
|
||||
```
|
||||
|
||||
Or on windows::
|
||||
Or on windows:
|
||||
|
||||
```cmd
|
||||
nim c compiler\nimfix\nimfix.nim
|
||||
move compiler\nimfix\nimfix.exe bin
|
||||
```
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Usage:
|
||||
|
||||
```cmd
|
||||
nimfix [options] projectfile.nim
|
||||
```
|
||||
|
||||
Options:
|
||||
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
|
||||
Usage:
|
||||
|
||||
* To search::
|
||||
nimgrep [options] PATTERN [(FILE/DIRECTORY)*/-]
|
||||
* To replace::
|
||||
nimgrep [options] PATTERN --replace REPLACEMENT (FILE/DIRECTORY)*/-
|
||||
* To list file names::
|
||||
nimgrep [options] --filenames [PATTERN] [(FILE/DIRECTORY)*]
|
||||
* To search:
|
||||
|
||||
nimgrep [options] PATTERN [(FILE/DIRECTORY)*/-]
|
||||
|
||||
* To replace:
|
||||
|
||||
nimgrep [options] PATTERN --replace REPLACEMENT (FILE/DIRECTORY)*/-
|
||||
|
||||
* To list file names:
|
||||
|
||||
nimgrep [options] --filenames [PATTERN] [(FILE/DIRECTORY)*]
|
||||
|
||||
Positional arguments, from left to right:
|
||||
1) PATTERN is either Regex (default) or Peg if `--peg` is specified.
|
||||
@@ -42,10 +47,11 @@ Options:
|
||||
to abort any time without touching the file
|
||||
--filenames just list filenames. Provide a PATTERN to find it in
|
||||
the filenames (not in the contents of a file) or run
|
||||
with empty pattern to just list all files::
|
||||
nimgrep --filenames # In current dir
|
||||
nimgrep --filenames "" DIRECTORY
|
||||
# Note empty pattern "", lists all files in DIRECTORY
|
||||
with empty pattern to just list all files:
|
||||
|
||||
nimgrep --filenames # In current dir
|
||||
nimgrep --filenames "" DIRECTORY
|
||||
# Note empty pattern "", lists all files in DIRECTORY
|
||||
* Interprete patterns:
|
||||
--peg PATTERN and PAT are Peg
|
||||
--re PATTERN and PAT are regular expressions (default)
|
||||
|
||||
@@ -72,11 +72,11 @@ Key description
|
||||
Many sections support the `files` key. Listed filenames
|
||||
can be separated by semicolon or the `files` key can be repeated. Wildcards
|
||||
in filenames are supported. If it is a directory name, all files in the
|
||||
directory are used::
|
||||
directory are used:
|
||||
|
||||
[Config]
|
||||
Files: "configDir"
|
||||
Files: "otherconfig/*.conf;otherconfig/*.cfg"
|
||||
[Config]
|
||||
Files: "configDir"
|
||||
Files: "otherconfig/*.conf;otherconfig/*.cfg"
|
||||
|
||||
|
||||
Config section
|
||||
|
||||
@@ -131,44 +131,44 @@ notation meaning
|
||||
Supported PEG grammar
|
||||
---------------------
|
||||
|
||||
The PEG parser implements this grammar (written in PEG syntax)::
|
||||
The PEG parser implements this grammar (written in PEG syntax):
|
||||
|
||||
# Example grammar of PEG in PEG syntax.
|
||||
# Comments start with '#'.
|
||||
# First symbol is the start symbol.
|
||||
# Example grammar of PEG in PEG syntax.
|
||||
# Comments start with '#'.
|
||||
# First symbol is the start symbol.
|
||||
|
||||
grammar <- rule* / expr
|
||||
grammar <- rule* / expr
|
||||
|
||||
identifier <- [A-Za-z][A-Za-z0-9_]*
|
||||
charsetchar <- "\\" . / [^\]]
|
||||
charset <- "[" "^"? (charsetchar ("-" charsetchar)?)+ "]"
|
||||
stringlit <- identifier? ("\"" ("\\" . / [^"])* "\"" /
|
||||
"'" ("\\" . / [^'])* "'")
|
||||
builtin <- "\\" identifier / [^\13\10]
|
||||
identifier <- [A-Za-z][A-Za-z0-9_]*
|
||||
charsetchar <- "\\" . / [^\]]
|
||||
charset <- "[" "^"? (charsetchar ("-" charsetchar)?)+ "]"
|
||||
stringlit <- identifier? ("\"" ("\\" . / [^"])* "\"" /
|
||||
"'" ("\\" . / [^'])* "'")
|
||||
builtin <- "\\" identifier / [^\13\10]
|
||||
|
||||
comment <- '#' @ \n
|
||||
ig <- (\s / comment)* # things to ignore
|
||||
comment <- '#' @ \n
|
||||
ig <- (\s / comment)* # things to ignore
|
||||
|
||||
rule <- identifier \s* "<-" expr ig
|
||||
identNoArrow <- identifier !(\s* "<-")
|
||||
prefixOpr <- ig '&' / ig '!' / ig '@' / ig '{@}' / ig '@@'
|
||||
literal <- ig identifier? '$' '^'? [0-9]+ / '$' / '^' /
|
||||
ig identNoArrow /
|
||||
ig charset /
|
||||
ig stringlit /
|
||||
ig builtin /
|
||||
ig '.' /
|
||||
ig '_' /
|
||||
(ig "(" expr ig ")") /
|
||||
(ig "{" expr? ig "}")
|
||||
postfixOpr <- ig '?' / ig '*' / ig '+'
|
||||
primary <- prefixOpr* (literal postfixOpr*)
|
||||
rule <- identifier \s* "<-" expr ig
|
||||
identNoArrow <- identifier !(\s* "<-")
|
||||
prefixOpr <- ig '&' / ig '!' / ig '@' / ig '{@}' / ig '@@'
|
||||
literal <- ig identifier? '$' '^'? [0-9]+ / '$' / '^' /
|
||||
ig identNoArrow /
|
||||
ig charset /
|
||||
ig stringlit /
|
||||
ig builtin /
|
||||
ig '.' /
|
||||
ig '_' /
|
||||
(ig "(" expr ig ")") /
|
||||
(ig "{" expr? ig "}")
|
||||
postfixOpr <- ig '?' / ig '*' / ig '+'
|
||||
primary <- prefixOpr* (literal postfixOpr*)
|
||||
|
||||
# Concatenation has higher priority than choice:
|
||||
# ``a b / c`` means ``(a b) / c``
|
||||
# Concatenation has higher priority than choice:
|
||||
# ``a b / c`` means ``(a b) / c``
|
||||
|
||||
seqExpr <- primary+
|
||||
expr <- seqExpr (ig "/" expr)*
|
||||
seqExpr <- primary+
|
||||
expr <- seqExpr (ig "/" expr)*
|
||||
|
||||
|
||||
**Note**: As a special syntactic extension if the whole PEG is only a single
|
||||
|
||||
@@ -56,9 +56,9 @@ backslashes are interpreted by the regular expression engine:
|
||||
A regular expression is a pattern that is matched against a subject string
|
||||
from left to right. Most characters stand for themselves in a pattern, and
|
||||
match the corresponding characters in the subject. As a trivial example,
|
||||
the pattern::
|
||||
the pattern:
|
||||
|
||||
The quick brown fox
|
||||
The quick brown fox
|
||||
|
||||
matches a portion of a subject string that is identical to itself.
|
||||
The power of regular expressions comes from the ability to include
|
||||
@@ -130,7 +130,7 @@ in patterns in a visible manner. There is no restriction on the appearance of
|
||||
non-printing characters, apart from the binary zero that terminates a pattern,
|
||||
but when a pattern is being prepared by text editing, it is usually easier to
|
||||
use one of the following escape sequences than the binary character it
|
||||
represents::
|
||||
represents:
|
||||
|
||||
============== ============================================================
|
||||
character meaning
|
||||
@@ -246,7 +246,7 @@ The fourth use of backslash is for certain `simple assertions`:idx:. An
|
||||
assertion specifies a condition that has to be met at a particular point in
|
||||
a match, without consuming any characters from the subject string. The use of
|
||||
subpatterns for more complicated assertions is described below. The
|
||||
backslashed assertions are::
|
||||
backslashed assertions are:
|
||||
|
||||
============== ============================================================
|
||||
assertion meaning
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
..
|
||||
Usage of this file:
|
||||
Add this in the beginning of *.rst file::
|
||||
Add this in the beginning of *.rst file:
|
||||
|
||||
.. default-role:: code
|
||||
.. include:: rstcommon.rst
|
||||
.. default-role:: code
|
||||
.. include:: rstcommon.rst
|
||||
|
||||
It's the current trick for brevity and compatibility with both Github and
|
||||
rst2html.py, considering that Github cannot highlight Nim in
|
||||
|
||||
20
doc/tut1.md
20
doc/tut1.md
@@ -45,24 +45,28 @@ We start the tour with a modified "hello world" program:
|
||||
```
|
||||
|
||||
|
||||
Save this code to the file "greetings.nim". Now compile and run it::
|
||||
|
||||
Save this code to the file "greetings.nim". Now compile and run it:
|
||||
```cmd
|
||||
nim compile --run greetings.nim
|
||||
```
|
||||
|
||||
With the ``--run`` [switch](nimc.html#compiler-usage-commandminusline-switches) Nim
|
||||
executes the file automatically after compilation. You can give your program
|
||||
command-line arguments by appending them after the filename::
|
||||
|
||||
command-line arguments by appending them after the filename:
|
||||
```cmd
|
||||
nim compile --run greetings.nim arg1 arg2
|
||||
```
|
||||
|
||||
Commonly used commands and switches have abbreviations, so you can also use::
|
||||
|
||||
Commonly used commands and switches have abbreviations, so you can also use:
|
||||
```cmd
|
||||
nim c -r greetings.nim
|
||||
```
|
||||
|
||||
This is a **debug version**.
|
||||
To compile a release version use::
|
||||
|
||||
To compile a release version use:
|
||||
```cmd
|
||||
nim c -d:release greetings.nim
|
||||
```
|
||||
|
||||
By default, the Nim compiler generates a large number of runtime checks
|
||||
aiming for your debugging pleasure. With ``-d:release`` some checks are
|
||||
|
||||
@@ -75,10 +75,10 @@ proc toLangSymbol*(linkText: PRstNode): LangSymbol =
|
||||
## Parses `linkText` into a more structured form using a state machine.
|
||||
##
|
||||
## This proc is designed to allow link syntax with operators even
|
||||
## without escaped backticks inside::
|
||||
## without escaped backticks inside:
|
||||
##
|
||||
## `proc *`_
|
||||
## `proc []`_
|
||||
## `proc *`_
|
||||
## `proc []`_
|
||||
##
|
||||
## This proc should be kept in sync with the `renderTypes` proc from
|
||||
## ``compiler/typesrenderer.nim``.
|
||||
|
||||
@@ -2172,7 +2172,7 @@ proc whichSection(p: RstParser): RstNodeKind =
|
||||
# for punctuation sequences that can be both tkAdornment and tkPunct
|
||||
if isMarkdownCodeBlock(p):
|
||||
return rnCodeBlock
|
||||
elif currentTok(p).symbol == "::":
|
||||
elif isRst(p) and currentTok(p).symbol == "::":
|
||||
return rnLiteralBlock
|
||||
elif currentTok(p).symbol == ".." and
|
||||
nextTok(p).kind in {tkWhite, tkIndent}:
|
||||
@@ -2362,8 +2362,10 @@ proc parseParagraph(p: var RstParser, result: PRstNode) =
|
||||
of tkIndent:
|
||||
if nextTok(p).kind == tkIndent:
|
||||
inc p.idx
|
||||
break
|
||||
elif currentTok(p).ival == currInd(p):
|
||||
break # blank line breaks paragraph for both Md & Rst
|
||||
elif currentTok(p).ival == currInd(p) or (
|
||||
isMd(p) and currentTok(p).ival > currInd(p)):
|
||||
# (Md allows adding additional indentation inside paragraphs)
|
||||
inc p.idx
|
||||
case whichSection(p)
|
||||
of rnParagraph, rnLeaf, rnHeadline, rnMarkdownHeadline,
|
||||
@@ -2377,7 +2379,8 @@ proc parseParagraph(p: var RstParser, result: PRstNode) =
|
||||
else:
|
||||
break
|
||||
of tkPunct:
|
||||
if (let literalBlockKind = whichRstLiteralBlock(p);
|
||||
if isRst(p) and (
|
||||
let literalBlockKind = whichRstLiteralBlock(p);
|
||||
literalBlockKind != lbNone):
|
||||
result.add newLeaf(":")
|
||||
inc p.idx # skip '::'
|
||||
@@ -2932,11 +2935,11 @@ proc parseSection(p: var RstParser, result: PRstNode) =
|
||||
elif currentTok(p).ival > currInd(p):
|
||||
if roPreferMarkdown in p.s.options: # Markdown => normal paragraphs
|
||||
if currentTok(p).ival - currInd(p) >= 4:
|
||||
rstMessage(p, mwRstStyle,
|
||||
"Markdown indented code not implemented")
|
||||
pushInd(p, currentTok(p).ival)
|
||||
parseSection(p, result)
|
||||
popInd(p)
|
||||
result.add parseLiteralBlock(p)
|
||||
else:
|
||||
pushInd(p, currentTok(p).ival)
|
||||
parseSection(p, result)
|
||||
popInd(p)
|
||||
else: # RST mode => block quotes
|
||||
pushInd(p, currentTok(p).ival)
|
||||
var a = newRstNodeA(p, rnBlockQuote)
|
||||
|
||||
@@ -377,13 +377,13 @@ proc renderRstToJsonNode(node: PRstNode): JsonNode =
|
||||
|
||||
proc renderRstToJson*(node: PRstNode): string =
|
||||
## Writes the given RST node as JSON that is in the form
|
||||
## ::
|
||||
## {
|
||||
## "kind":string node.kind,
|
||||
## "text":optional string node.text,
|
||||
## "level":optional int node.level,
|
||||
## "sons":optional node array
|
||||
## }
|
||||
##
|
||||
## {
|
||||
## "kind":string node.kind,
|
||||
## "text":optional string node.text,
|
||||
## "level":optional int node.level,
|
||||
## "sons":optional node array
|
||||
## }
|
||||
renderRstToJsonNode(node).pretty
|
||||
|
||||
proc renderRstToText*(node: PRstNode): string =
|
||||
|
||||
@@ -57,9 +57,10 @@ proc memoryLock*(a1: pointer, a2: int) =
|
||||
proc memoryLockAll*(flags: int) =
|
||||
## Locks all memory for the running process to prevent swapping.
|
||||
##
|
||||
## example::
|
||||
##
|
||||
## example:
|
||||
## ```nim
|
||||
## memoryLockAll(MCL_CURRENT or MCL_FUTURE)
|
||||
## ```
|
||||
if mlockall(flags.cint) != 0:
|
||||
raise newException(OSError, $strerror(errno))
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
|
||||
## This module implements the basics for Linux distribution ("distro")
|
||||
## detection and the OS's native package manager. Its primary purpose is to
|
||||
## produce output for Nimble packages, like::
|
||||
## produce output for Nimble packages, like:
|
||||
##
|
||||
## To complete the installation, run:
|
||||
## To complete the installation, run:
|
||||
##
|
||||
## sudo apt-get install libblas-dev
|
||||
## sudo apt-get install libvoodoo
|
||||
## sudo apt-get install libblas-dev
|
||||
## sudo apt-get install libvoodoo
|
||||
##
|
||||
## The above output could be the result of a code snippet like:
|
||||
##
|
||||
|
||||
@@ -34,9 +34,9 @@
|
||||
## var nim = "Nim"
|
||||
## echo h1(a(href="https://nim-lang.org", nim))
|
||||
##
|
||||
## Writes the string::
|
||||
## Writes the string:
|
||||
##
|
||||
## <h1><a href="https://nim-lang.org">Nim</a></h1>
|
||||
## <h1><a href="https://nim-lang.org">Nim</a></h1>
|
||||
##
|
||||
|
||||
import
|
||||
|
||||
@@ -2294,11 +2294,12 @@ iterator walkDir*(dir: string; relative = false, checkDir = false):
|
||||
##
|
||||
## **Example:**
|
||||
##
|
||||
## This directory structure::
|
||||
## dirA / dirB / fileB1.txt
|
||||
## / dirC
|
||||
## / fileA1.txt
|
||||
## / fileA2.txt
|
||||
## This directory structure:
|
||||
##
|
||||
## dirA / dirB / fileB1.txt
|
||||
## / dirC
|
||||
## / fileA1.txt
|
||||
## / fileA2.txt
|
||||
##
|
||||
## and this code:
|
||||
runnableExamples("-r:off"):
|
||||
|
||||
@@ -2058,9 +2058,9 @@ func parsePeg*(pattern: string, filename = "pattern", line = 1, col = 0): Peg =
|
||||
|
||||
func peg*(pattern: string): Peg =
|
||||
## constructs a Peg object from the `pattern`. The short name has been
|
||||
## chosen to encourage its use as a raw string modifier::
|
||||
## chosen to encourage its use as a raw string modifier:
|
||||
##
|
||||
## peg"{\ident} \s* '=' \s* {.*}"
|
||||
## peg"{\ident} \s* '=' \s* {.*}"
|
||||
result = parsePeg(pattern, "pattern")
|
||||
|
||||
func escapePeg*(s: string): string =
|
||||
|
||||
@@ -171,9 +171,9 @@ For strings and numeric types the optional argument is a so-called
|
||||
|
||||
# Standard format specifiers for strings, integers and floats
|
||||
|
||||
The general form of a standard format specifier is::
|
||||
The general form of a standard format specifier is:
|
||||
|
||||
[[fill]align][sign][#][0][minimumwidth][.precision][type]
|
||||
[[fill]align][sign][#][0][minimumwidth][.precision][type]
|
||||
|
||||
The square brackets `[]` indicate an optional element.
|
||||
|
||||
@@ -423,9 +423,9 @@ proc formatInt(n: SomeNumber; radix: int; spec: StandardFormatSpecifier): string
|
||||
proc parseStandardFormatSpecifier*(s: string; start = 0;
|
||||
ignoreUnknownSuffix = false): StandardFormatSpecifier =
|
||||
## An exported helper proc that parses the "standard format specifiers",
|
||||
## as specified by the grammar::
|
||||
## as specified by the grammar:
|
||||
##
|
||||
## [[fill]align][sign][#][0][minimumwidth][.precision][type]
|
||||
## [[fill]align][sign][#][0][minimumwidth][.precision][type]
|
||||
##
|
||||
## This is only of interest if you want to write a custom `format` proc that
|
||||
## should support the standard format specifiers. If `ignoreUnknownSuffix` is true,
|
||||
|
||||
@@ -778,8 +778,8 @@ macro `<>`*(x: untyped): untyped =
|
||||
## .. code-block:: nim
|
||||
## <>a(href="http://nim-lang.org", newText("Nim rules."))
|
||||
##
|
||||
## Produces an XML tree for::
|
||||
## Produces an XML tree for:
|
||||
##
|
||||
## <a href="http://nim-lang.org">Nim rules.</a>
|
||||
## <a href="http://nim-lang.org">Nim rules.</a>
|
||||
##
|
||||
result = xmlConstructor(x)
|
||||
|
||||
@@ -91,14 +91,15 @@
|
||||
## Sample output
|
||||
## -------------
|
||||
## The program should output something similar to this, but keep in mind that
|
||||
## exact results may vary in the real world::
|
||||
## Hello World!
|
||||
## Pretend I'm doing useful work...
|
||||
## Pretend I'm doing useful work...
|
||||
## Pretend I'm doing useful work...
|
||||
## Pretend I'm doing useful work...
|
||||
## Pretend I'm doing useful work...
|
||||
## Another message
|
||||
## exact results may vary in the real world:
|
||||
##
|
||||
## Hello World!
|
||||
## Pretend I'm doing useful work...
|
||||
## Pretend I'm doing useful work...
|
||||
## Pretend I'm doing useful work...
|
||||
## Pretend I'm doing useful work...
|
||||
## Pretend I'm doing useful work...
|
||||
## Another message
|
||||
##
|
||||
## Passing Channels Safely
|
||||
## -----------------------
|
||||
|
||||
@@ -7,6 +7,8 @@ discard """
|
||||
|
||||
[Suite] RST indentation
|
||||
|
||||
[Suite] Markdown indentation
|
||||
|
||||
[Suite] Warnings
|
||||
|
||||
[Suite] RST include directive
|
||||
@@ -124,12 +126,12 @@ suite "RST parsing":
|
||||
check(dedent"""
|
||||
Paragraph::
|
||||
|
||||
>x""".toAst == expected)
|
||||
>x""".toAst(rstOptions = preferRst) == expected)
|
||||
|
||||
check(dedent"""
|
||||
Paragraph::
|
||||
|
||||
>x""".toAst == expected)
|
||||
>x""".toAst(rstOptions = preferRst) == expected)
|
||||
|
||||
test "RST quoted literal blocks, :: at a separate line":
|
||||
let expected =
|
||||
@@ -148,7 +150,7 @@ suite "RST parsing":
|
||||
::
|
||||
|
||||
>x
|
||||
>>y""".toAst == expected)
|
||||
>>y""".toAst(rstOptions = preferRst) == expected)
|
||||
|
||||
check(dedent"""
|
||||
Paragraph
|
||||
@@ -156,7 +158,7 @@ suite "RST parsing":
|
||||
::
|
||||
|
||||
>x
|
||||
>>y""".toAst == expected)
|
||||
>>y""".toAst(rstOptions = preferRst) == expected)
|
||||
|
||||
test "Markdown quoted blocks":
|
||||
check(dedent"""
|
||||
@@ -779,7 +781,7 @@ suite "RST parsing":
|
||||
|
||||
code
|
||||
|
||||
""".toAst ==
|
||||
""".toAst(rstOptions = preferRst) ==
|
||||
dedent"""
|
||||
rnInner
|
||||
rnLeaf 'Check'
|
||||
@@ -788,6 +790,32 @@ suite "RST parsing":
|
||||
rnLeaf 'code'
|
||||
""")
|
||||
|
||||
test "Markdown indented code blocks":
|
||||
check(dedent"""
|
||||
See
|
||||
|
||||
some code""".toAst ==
|
||||
dedent"""
|
||||
rnInner
|
||||
rnInner
|
||||
rnLeaf 'See'
|
||||
rnLiteralBlock
|
||||
rnLeaf 'some code'
|
||||
""")
|
||||
|
||||
# not a code block -- no blank line before:
|
||||
check(dedent"""
|
||||
See
|
||||
some code""".toAst ==
|
||||
dedent"""
|
||||
rnInner
|
||||
rnLeaf 'See'
|
||||
rnLeaf ' '
|
||||
rnLeaf 'some'
|
||||
rnLeaf ' '
|
||||
rnLeaf 'code'
|
||||
""")
|
||||
|
||||
suite "RST tables":
|
||||
|
||||
test "formatting in tables works":
|
||||
@@ -1238,6 +1266,31 @@ suite "RST indentation":
|
||||
rnLeaf 'term3definition2'
|
||||
""")
|
||||
|
||||
suite "Markdown indentation":
|
||||
test "Markdown paragraph indentation":
|
||||
# Additional spaces (<=3) of indentation does not break the paragraph.
|
||||
# TODO: in 2nd case de-indentation causes paragraph to break, this is
|
||||
# reasonable but does not seem to conform the Markdown spec.
|
||||
check(dedent"""
|
||||
Start1
|
||||
stop1
|
||||
|
||||
Start2
|
||||
stop2
|
||||
""".toAst ==
|
||||
dedent"""
|
||||
rnInner
|
||||
rnParagraph
|
||||
rnLeaf 'Start1'
|
||||
rnLeaf ' '
|
||||
rnLeaf 'stop1'
|
||||
rnParagraph
|
||||
rnLeaf 'Start2'
|
||||
rnParagraph
|
||||
rnLeaf 'stop2'
|
||||
rnLeaf ' '
|
||||
""")
|
||||
|
||||
suite "Warnings":
|
||||
test "warnings for broken footnotes/links/substitutions":
|
||||
let input = dedent"""
|
||||
|
||||
@@ -632,7 +632,7 @@ Test literal block
|
||||
::
|
||||
|
||||
check """
|
||||
let output1 = input1.toHtml
|
||||
let output1 = input1.toHtml(preferRst)
|
||||
doAssert "<pre>" in output1
|
||||
|
||||
test "Markdown code block":
|
||||
|
||||
Reference in New Issue
Block a user