mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
doc: Trim .txt files trailing whitespace
via OSX: find . -name '*.txt' -exec sed -i '' -E 's/[[:space:]]+$//' {} +
This commit is contained in:
@@ -20,7 +20,7 @@ English word To use Notes
|
||||
------------------- ------------ --------------------------------------
|
||||
initialize initT ``init`` is used to create a
|
||||
value type ``T``
|
||||
new newP ``new`` is used to create a
|
||||
new newP ``new`` is used to create a
|
||||
reference type ``P``
|
||||
find find should return the position where
|
||||
something was found; for a bool result
|
||||
|
||||
@@ -28,7 +28,7 @@ The documentation consists of several documents:
|
||||
builtin templating system.
|
||||
|
||||
- | `Term rewriting macros <trmacros.html>`_
|
||||
| Term rewriting macros enhance the compilation process with user defined
|
||||
| Term rewriting macros enhance the compilation process with user defined
|
||||
optimizations.
|
||||
|
||||
- | `Internal documentation <intern.html>`_
|
||||
|
||||
402
doc/endb.txt
402
doc/endb.txt
@@ -1,203 +1,203 @@
|
||||
==============================================
|
||||
Embedded Nim Debugger (ENDB) User Guide
|
||||
==============================================
|
||||
|
||||
:Author: Andreas Rumpf
|
||||
:Version: |nimversion|
|
||||
|
||||
.. contents::
|
||||
|
||||
==============================================
|
||||
Embedded Nim Debugger (ENDB) User Guide
|
||||
==============================================
|
||||
|
||||
:Author: Andreas Rumpf
|
||||
:Version: |nimversion|
|
||||
|
||||
.. contents::
|
||||
|
||||
**WARNING**: ENDB is not maintained anymore! Please help if you're interested
|
||||
in this tool.
|
||||
|
||||
Nim comes with a platform independent debugger -
|
||||
the Embedded Nim Debugger (ENDB). The debugger is
|
||||
*embedded* into your executable if it has been
|
||||
compiled with the ``--debugger:on`` command line option.
|
||||
This also defines the conditional symbol ``ENDB`` for you.
|
||||
|
||||
Note: You must not compile your program with the ``--app:gui``
|
||||
command line option because then there would be no console
|
||||
available for the debugger.
|
||||
|
||||
If you start your program the debugger will immediately show
|
||||
a prompt on the console. You can now enter a command. The next sections
|
||||
deal with the possible commands. As usual in Nim in all commands
|
||||
underscores and case do not matter. Optional components of a command
|
||||
are listed in brackets ``[...]`` here.
|
||||
|
||||
|
||||
General Commands
|
||||
================
|
||||
|
||||
``h``, ``help``
|
||||
Display a quick reference of the possible commands.
|
||||
|
||||
``q``, ``quit``
|
||||
Quit the debugger and the program.
|
||||
|
||||
<ENTER>
|
||||
(Without any typed command) repeat the previous debugger command.
|
||||
If there is no previous command, ``step_into`` is assumed.
|
||||
|
||||
Executing Commands
|
||||
==================
|
||||
|
||||
``s``, ``step_into``
|
||||
Single step, stepping into routine calls.
|
||||
|
||||
``n``, ``step_over``
|
||||
Single step, without stepping into routine calls.
|
||||
|
||||
``f``, ``skip_current``
|
||||
Continue execution until the current routine finishes.
|
||||
|
||||
``c``, ``continue``
|
||||
Continue execution until the next breakpoint.
|
||||
|
||||
``i``, ``ignore``
|
||||
Continue execution, ignore all breakpoints. This effectively quits
|
||||
the debugger and runs the program until it finishes.
|
||||
|
||||
|
||||
Breakpoint Commands
|
||||
===================
|
||||
|
||||
``b``, ``setbreak`` [fromline [toline]] [file]
|
||||
Set a new breakpoint for the given file
|
||||
and line numbers. If no file is given, the current execution point's
|
||||
filename is used. If the filename has no extension, ``.nim`` is
|
||||
appended for your convenience.
|
||||
If no line numbers are given, the current execution point's
|
||||
line is used. If both ``fromline`` and ``toline`` are given the
|
||||
breakpoint contains a line number range. Some examples if it is still
|
||||
unclear:
|
||||
|
||||
* ``b 12 15 thallo`` creates a breakpoint that
|
||||
will be triggered if the instruction pointer reaches one of the
|
||||
lines 12-15 in the file ``thallo.nim``.
|
||||
* ``b 12 thallo`` creates a breakpoint that
|
||||
will be triggered if the instruction pointer reaches the
|
||||
line 12 in the file ``thallo.nim``.
|
||||
* ``b 12`` creates a breakpoint that
|
||||
will be triggered if the instruction pointer reaches the
|
||||
line 12 in the current file.
|
||||
* ``b`` creates a breakpoint that
|
||||
will be triggered if the instruction pointer reaches the
|
||||
current line in the current file again.
|
||||
|
||||
``breakpoints``
|
||||
Display the entire breakpoint list.
|
||||
|
||||
``disable`` <identifier>
|
||||
Disable a breakpoint. It remains disabled until you turn it on again
|
||||
with the ``enable`` command.
|
||||
|
||||
``enable`` <identifier>
|
||||
Enable a breakpoint.
|
||||
|
||||
Often it happens when debugging that you keep retyping the breakpoints again
|
||||
and again because they are lost when you restart your program. This is not
|
||||
necessary: A special pragma has been defined for this:
|
||||
|
||||
|
||||
The ``breakpoint`` pragma
|
||||
-------------------------
|
||||
|
||||
The ``breakpoint`` pragma is syntactically a statement. It can be used
|
||||
to mark the *following line* as a breakpoint:
|
||||
|
||||
.. code-block:: Nim
|
||||
write("1")
|
||||
{.breakpoint: "before_write_2".}
|
||||
write("2")
|
||||
|
||||
The name of the breakpoint here is ``before_write_2``. Of course the
|
||||
breakpoint's name is optional - the compiler will generate one for you
|
||||
if you leave it out.
|
||||
|
||||
Code for the ``breakpoint`` pragma is only generated if the debugger
|
||||
is turned on, so you don't need to remove it from your source code after
|
||||
debugging.
|
||||
|
||||
|
||||
The ``watchpoint`` pragma
|
||||
-------------------------
|
||||
|
||||
The ``watchpoint`` pragma is syntactically a statement. It can be used
|
||||
to mark a location as a watchpoint:
|
||||
|
||||
.. code-block:: Nim
|
||||
var a: array [0..20, int]
|
||||
|
||||
{.watchpoint: a[3].}
|
||||
for i in 0 .. 20: a[i] = i
|
||||
|
||||
ENDB then writes a stack trace whenever the content of the location ``a[3]``
|
||||
changes. The current implementation only tracks a hash value of the location's
|
||||
contents and so locations that are not word sized may encounter false
|
||||
negatives in very rare cases.
|
||||
|
||||
Code for the ``watchpoint`` pragma is only generated if the debugger
|
||||
is turned on, so you don't need to remove it from your source code after
|
||||
debugging.
|
||||
|
||||
Due to the primitive implementation watchpoints are even slower than
|
||||
breakpoints: After *every* executed Nim code line it is checked whether the
|
||||
location changed.
|
||||
|
||||
|
||||
Data Display Commands
|
||||
=====================
|
||||
|
||||
``e``, ``eval`` <exp>
|
||||
Evaluate the expression <exp>. Note that ENDB has no full-blown expression
|
||||
evaluator built-in. So expressions are limited:
|
||||
|
||||
* To display global variables prefix their names with their
|
||||
owning module: ``nim1.globalVar``
|
||||
* To display local variables or parameters just type in
|
||||
their name: ``localVar``. If you want to inspect variables that are not
|
||||
in the current stack frame, use the ``up`` or ``down`` command.
|
||||
|
||||
Unfortunately, only inspecting variables is possible at the moment. Maybe
|
||||
a future version will implement a full-blown Nim expression evaluator,
|
||||
but this is not easy to do and would bloat the debugger's code.
|
||||
|
||||
Since displaying the whole data structures is often not needed and
|
||||
painfully slow, the debugger uses a *maximal display depth* concept for
|
||||
displaying.
|
||||
|
||||
You can alter the maximal display depth with the ``maxdisplay``
|
||||
command.
|
||||
|
||||
``maxdisplay`` <natural>
|
||||
Sets the maximal display depth to the given integer value. A value of 0
|
||||
means there is no maximal display depth. Default is 3.
|
||||
|
||||
``o``, ``out`` <filename> <exp>
|
||||
Evaluate the expression <exp> and store its string representation into a
|
||||
file named <filename>. If the file does not exist, it will be created,
|
||||
otherwise it will be opened for appending.
|
||||
|
||||
``w``, ``where``
|
||||
Display the current execution point.
|
||||
|
||||
``u``, ``up``
|
||||
Go up in the call stack.
|
||||
|
||||
``d``, ``down``
|
||||
Go down in the call stack.
|
||||
|
||||
``stackframe`` [file]
|
||||
Displays the content of the current stack frame in ``stdout`` or
|
||||
appends it to the file, depending on whether a file is given.
|
||||
|
||||
``callstack``
|
||||
Display the entire call stack (but not its content).
|
||||
|
||||
``l``, ``locals``
|
||||
Display the available local variables in the current stack frame.
|
||||
|
||||
``g``, ``globals``
|
||||
Display all the global variables that are available for inspection.
|
||||
|
||||
Nim comes with a platform independent debugger -
|
||||
the Embedded Nim Debugger (ENDB). The debugger is
|
||||
*embedded* into your executable if it has been
|
||||
compiled with the ``--debugger:on`` command line option.
|
||||
This also defines the conditional symbol ``ENDB`` for you.
|
||||
|
||||
Note: You must not compile your program with the ``--app:gui``
|
||||
command line option because then there would be no console
|
||||
available for the debugger.
|
||||
|
||||
If you start your program the debugger will immediately show
|
||||
a prompt on the console. You can now enter a command. The next sections
|
||||
deal with the possible commands. As usual in Nim in all commands
|
||||
underscores and case do not matter. Optional components of a command
|
||||
are listed in brackets ``[...]`` here.
|
||||
|
||||
|
||||
General Commands
|
||||
================
|
||||
|
||||
``h``, ``help``
|
||||
Display a quick reference of the possible commands.
|
||||
|
||||
``q``, ``quit``
|
||||
Quit the debugger and the program.
|
||||
|
||||
<ENTER>
|
||||
(Without any typed command) repeat the previous debugger command.
|
||||
If there is no previous command, ``step_into`` is assumed.
|
||||
|
||||
Executing Commands
|
||||
==================
|
||||
|
||||
``s``, ``step_into``
|
||||
Single step, stepping into routine calls.
|
||||
|
||||
``n``, ``step_over``
|
||||
Single step, without stepping into routine calls.
|
||||
|
||||
``f``, ``skip_current``
|
||||
Continue execution until the current routine finishes.
|
||||
|
||||
``c``, ``continue``
|
||||
Continue execution until the next breakpoint.
|
||||
|
||||
``i``, ``ignore``
|
||||
Continue execution, ignore all breakpoints. This effectively quits
|
||||
the debugger and runs the program until it finishes.
|
||||
|
||||
|
||||
Breakpoint Commands
|
||||
===================
|
||||
|
||||
``b``, ``setbreak`` [fromline [toline]] [file]
|
||||
Set a new breakpoint for the given file
|
||||
and line numbers. If no file is given, the current execution point's
|
||||
filename is used. If the filename has no extension, ``.nim`` is
|
||||
appended for your convenience.
|
||||
If no line numbers are given, the current execution point's
|
||||
line is used. If both ``fromline`` and ``toline`` are given the
|
||||
breakpoint contains a line number range. Some examples if it is still
|
||||
unclear:
|
||||
|
||||
* ``b 12 15 thallo`` creates a breakpoint that
|
||||
will be triggered if the instruction pointer reaches one of the
|
||||
lines 12-15 in the file ``thallo.nim``.
|
||||
* ``b 12 thallo`` creates a breakpoint that
|
||||
will be triggered if the instruction pointer reaches the
|
||||
line 12 in the file ``thallo.nim``.
|
||||
* ``b 12`` creates a breakpoint that
|
||||
will be triggered if the instruction pointer reaches the
|
||||
line 12 in the current file.
|
||||
* ``b`` creates a breakpoint that
|
||||
will be triggered if the instruction pointer reaches the
|
||||
current line in the current file again.
|
||||
|
||||
``breakpoints``
|
||||
Display the entire breakpoint list.
|
||||
|
||||
``disable`` <identifier>
|
||||
Disable a breakpoint. It remains disabled until you turn it on again
|
||||
with the ``enable`` command.
|
||||
|
||||
``enable`` <identifier>
|
||||
Enable a breakpoint.
|
||||
|
||||
Often it happens when debugging that you keep retyping the breakpoints again
|
||||
and again because they are lost when you restart your program. This is not
|
||||
necessary: A special pragma has been defined for this:
|
||||
|
||||
|
||||
The ``breakpoint`` pragma
|
||||
-------------------------
|
||||
|
||||
The ``breakpoint`` pragma is syntactically a statement. It can be used
|
||||
to mark the *following line* as a breakpoint:
|
||||
|
||||
.. code-block:: Nim
|
||||
write("1")
|
||||
{.breakpoint: "before_write_2".}
|
||||
write("2")
|
||||
|
||||
The name of the breakpoint here is ``before_write_2``. Of course the
|
||||
breakpoint's name is optional - the compiler will generate one for you
|
||||
if you leave it out.
|
||||
|
||||
Code for the ``breakpoint`` pragma is only generated if the debugger
|
||||
is turned on, so you don't need to remove it from your source code after
|
||||
debugging.
|
||||
|
||||
|
||||
The ``watchpoint`` pragma
|
||||
-------------------------
|
||||
|
||||
The ``watchpoint`` pragma is syntactically a statement. It can be used
|
||||
to mark a location as a watchpoint:
|
||||
|
||||
.. code-block:: Nim
|
||||
var a: array [0..20, int]
|
||||
|
||||
{.watchpoint: a[3].}
|
||||
for i in 0 .. 20: a[i] = i
|
||||
|
||||
ENDB then writes a stack trace whenever the content of the location ``a[3]``
|
||||
changes. The current implementation only tracks a hash value of the location's
|
||||
contents and so locations that are not word sized may encounter false
|
||||
negatives in very rare cases.
|
||||
|
||||
Code for the ``watchpoint`` pragma is only generated if the debugger
|
||||
is turned on, so you don't need to remove it from your source code after
|
||||
debugging.
|
||||
|
||||
Due to the primitive implementation watchpoints are even slower than
|
||||
breakpoints: After *every* executed Nim code line it is checked whether the
|
||||
location changed.
|
||||
|
||||
|
||||
Data Display Commands
|
||||
=====================
|
||||
|
||||
``e``, ``eval`` <exp>
|
||||
Evaluate the expression <exp>. Note that ENDB has no full-blown expression
|
||||
evaluator built-in. So expressions are limited:
|
||||
|
||||
* To display global variables prefix their names with their
|
||||
owning module: ``nim1.globalVar``
|
||||
* To display local variables or parameters just type in
|
||||
their name: ``localVar``. If you want to inspect variables that are not
|
||||
in the current stack frame, use the ``up`` or ``down`` command.
|
||||
|
||||
Unfortunately, only inspecting variables is possible at the moment. Maybe
|
||||
a future version will implement a full-blown Nim expression evaluator,
|
||||
but this is not easy to do and would bloat the debugger's code.
|
||||
|
||||
Since displaying the whole data structures is often not needed and
|
||||
painfully slow, the debugger uses a *maximal display depth* concept for
|
||||
displaying.
|
||||
|
||||
You can alter the maximal display depth with the ``maxdisplay``
|
||||
command.
|
||||
|
||||
``maxdisplay`` <natural>
|
||||
Sets the maximal display depth to the given integer value. A value of 0
|
||||
means there is no maximal display depth. Default is 3.
|
||||
|
||||
``o``, ``out`` <filename> <exp>
|
||||
Evaluate the expression <exp> and store its string representation into a
|
||||
file named <filename>. If the file does not exist, it will be created,
|
||||
otherwise it will be opened for appending.
|
||||
|
||||
``w``, ``where``
|
||||
Display the current execution point.
|
||||
|
||||
``u``, ``up``
|
||||
Go up in the call stack.
|
||||
|
||||
``d``, ``down``
|
||||
Go down in the call stack.
|
||||
|
||||
``stackframe`` [file]
|
||||
Displays the content of the current stack frame in ``stdout`` or
|
||||
appends it to the file, depending on whether a file is given.
|
||||
|
||||
``callstack``
|
||||
Display the entire call stack (but not its content).
|
||||
|
||||
``l``, ``locals``
|
||||
Display the available local variables in the current stack frame.
|
||||
|
||||
``g``, ``globals``
|
||||
Display all the global variables that are available for inspection.
|
||||
|
||||
46
doc/estp.txt
46
doc/estp.txt
@@ -1,30 +1,30 @@
|
||||
===================================================
|
||||
Embedded Stack Trace Profiler (ESTP) User Guide
|
||||
===================================================
|
||||
|
||||
:Author: Andreas Rumpf
|
||||
:Version: |nimversion|
|
||||
|
||||
|
||||
Nim comes with a platform independent profiler -
|
||||
the Embedded Stack Trace Profiler (ESTP). The profiler
|
||||
is *embedded* into your executable. To activate the profiler you need to do:
|
||||
===================================================
|
||||
Embedded Stack Trace Profiler (ESTP) User Guide
|
||||
===================================================
|
||||
|
||||
* compile your program with the ``--profiler:on --stackTrace:on`` command
|
||||
:Author: Andreas Rumpf
|
||||
:Version: |nimversion|
|
||||
|
||||
|
||||
Nim comes with a platform independent profiler -
|
||||
the Embedded Stack Trace Profiler (ESTP). The profiler
|
||||
is *embedded* into your executable. To activate the profiler you need to do:
|
||||
|
||||
* compile your program with the ``--profiler:on --stackTrace:on`` command
|
||||
line options
|
||||
* import the ``nimprof`` module
|
||||
* run your program as usual.
|
||||
|
||||
You can in fact look at ``nimprof``'s source code to see how to implement
|
||||
You can in fact look at ``nimprof``'s source code to see how to implement
|
||||
your own profiler.
|
||||
|
||||
The setting ``--profiler:on`` defines the conditional symbol ``profiler``.
|
||||
|
||||
After your program has finished the profiler will create a
|
||||
|
||||
The setting ``--profiler:on`` defines the conditional symbol ``profiler``.
|
||||
|
||||
After your program has finished the profiler will create a
|
||||
file ``profile_results.txt`` containing the profiling results.
|
||||
|
||||
Since the profiler works by examining stack traces, it's essential that
|
||||
the option ``--stackTrace:on`` is active! Unfortunately this means that a
|
||||
the option ``--stackTrace:on`` is active! Unfortunately this means that a
|
||||
profiling build is much slower than a release build.
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ Memory profiler
|
||||
===============
|
||||
|
||||
You can also use ESTP as a memory profiler to see which stack traces allocate
|
||||
the most memory and thus create the most GC pressure. It may also help to
|
||||
the most memory and thus create the most GC pressure. It may also help to
|
||||
find memory leaks. To activate the memory profiler you need to do:
|
||||
|
||||
* compile your program with the ``--profiler:off --stackTrace:on -d:memProfiler``
|
||||
@@ -40,22 +40,22 @@ find memory leaks. To activate the memory profiler you need to do:
|
||||
* import the ``nimprof`` module
|
||||
* run your program as usual.
|
||||
|
||||
Define the symbol ``ignoreAllocationSize`` so that only the number of
|
||||
Define the symbol ``ignoreAllocationSize`` so that only the number of
|
||||
allocations is counted and the sizes of the memory allocations do not matter.
|
||||
|
||||
|
||||
Example results file
|
||||
====================
|
||||
|
||||
The results file lists stack traces ordered by significance.
|
||||
The results file lists stack traces ordered by significance.
|
||||
|
||||
The following example file has been generated by profiling the Nim compiler
|
||||
itself: It shows that in total 5.4% of the runtime has been spent
|
||||
itself: It shows that in total 5.4% of the runtime has been spent
|
||||
in ``crcFromRope`` or its children.
|
||||
|
||||
In general the stack traces show you immediately where the problem is because
|
||||
the trace acts like an explanation; in traditional profilers you can only find
|
||||
expensive leaf functions easily but the *reason* why they are invoked
|
||||
expensive leaf functions easily but the *reason* why they are invoked
|
||||
often remains mysterious.
|
||||
|
||||
::
|
||||
|
||||
@@ -4,8 +4,8 @@ Source Code Filters
|
||||
|
||||
.. contents::
|
||||
|
||||
A `Source Code Filter` transforms the input character stream to an in-memory
|
||||
output stream before parsing. A filter can be used to provide templating
|
||||
A `Source Code Filter` transforms the input character stream to an in-memory
|
||||
output stream before parsing. A filter can be used to provide templating
|
||||
systems or preprocessors.
|
||||
|
||||
To use a filter for a source file the *shebang* notation is used::
|
||||
@@ -52,7 +52,7 @@ Parameters and their defaults:
|
||||
|
||||
``sub: string = ""``
|
||||
the substring that is searched for
|
||||
|
||||
|
||||
``by: string = ""``
|
||||
the string the substring is replaced with
|
||||
|
||||
@@ -71,7 +71,7 @@ Parameters and their defaults:
|
||||
|
||||
``leading: bool = true``
|
||||
strip leading whitespace
|
||||
|
||||
|
||||
``trailing: bool = true``
|
||||
strip trailing whitespace
|
||||
|
||||
@@ -89,16 +89,16 @@ Parameters and their defaults:
|
||||
|
||||
``metaChar: char = '#'``
|
||||
prefix for a line that contains Nim code
|
||||
|
||||
|
||||
``subsChar: char = '$'``
|
||||
prefix for a Nim expression within a template line
|
||||
|
||||
|
||||
``conc: string = " & "``
|
||||
the operation for concatenation
|
||||
|
||||
|
||||
``emit: string = "result.add"``
|
||||
the operation to emit a string literal
|
||||
|
||||
|
||||
``toString: string = "$"``
|
||||
the operation that is applied to each expression
|
||||
|
||||
@@ -106,7 +106,7 @@ Example::
|
||||
|
||||
#! stdtmpl | standard
|
||||
#proc generateHTMLPage(title, currentTab, content: string,
|
||||
# tabs: openArray[string]): string =
|
||||
# tabs: openArray[string]): string =
|
||||
# result = ""
|
||||
<head><title>$title</title></head>
|
||||
<body>
|
||||
@@ -114,7 +114,7 @@ Example::
|
||||
<ul>
|
||||
#for tab in items(tabs):
|
||||
#if currentTab == tab:
|
||||
<li><a id="selected"
|
||||
<li><a id="selected"
|
||||
#else:
|
||||
<li><a
|
||||
#end if
|
||||
@@ -132,11 +132,11 @@ The filter transforms this into:
|
||||
|
||||
.. code-block:: nim
|
||||
proc generateHTMLPage(title, currentTab, content: string,
|
||||
tabs: openArray[string]): string =
|
||||
tabs: openArray[string]): string =
|
||||
result = ""
|
||||
result.add("<head><title>" & $(title) & "</title></head>\n" &
|
||||
"<body>\n" &
|
||||
" <div id=\"menu\">\n" &
|
||||
result.add("<head><title>" & $(title) & "</title></head>\n" &
|
||||
"<body>\n" &
|
||||
" <div id=\"menu\">\n" &
|
||||
" <ul>\n")
|
||||
for tab in items(tabs):
|
||||
if currentTab == tab:
|
||||
@@ -146,17 +146,17 @@ The filter transforms this into:
|
||||
#end
|
||||
result.add(" href=\"" & $(tab) & ".html\">" & $(tab) & "</a></li>\n")
|
||||
#end
|
||||
result.add(" </ul>\n" &
|
||||
" </div>\n" &
|
||||
" <div id=\"content\">\n" &
|
||||
" " & $(content) & "\n" &
|
||||
" A dollar: $.\n" &
|
||||
" </div>\n" &
|
||||
result.add(" </ul>\n" &
|
||||
" </div>\n" &
|
||||
" <div id=\"content\">\n" &
|
||||
" " & $(content) & "\n" &
|
||||
" A dollar: $.\n" &
|
||||
" </div>\n" &
|
||||
"</body>\n")
|
||||
|
||||
|
||||
|
||||
Each line that does not start with the meta character (ignoring leading
|
||||
whitespace) is converted to a string literal that is added to ``result``.
|
||||
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
|
||||
@@ -174,14 +174,14 @@ writes the template code directly to a file::
|
||||
|
||||
#! stdtmpl(emit="f.write") | standard
|
||||
#proc writeHTMLPage(f: File, title, currentTab, content: string,
|
||||
# tabs: openArray[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"
|
||||
<li><a id="selected"
|
||||
#else:
|
||||
<li><a
|
||||
#end if
|
||||
|
||||
28
doc/gc.txt
28
doc/gc.txt
@@ -37,13 +37,13 @@ The cycle collector can be en-/disabled independently from the other parts of
|
||||
the GC with ``GC_enableMarkAndSweep`` and ``GC_disableMarkAndSweep``. The
|
||||
compiler analyses the types for their possibility to build cycles, but often
|
||||
it is necessary to help this analysis with the ``acyclic`` pragma (see
|
||||
`acyclic <manual.html#acyclic-pragma>`_ for further information).
|
||||
`acyclic <manual.html#acyclic-pragma>`_ for further information).
|
||||
|
||||
You can also use the ``acyclic`` pragma for data that is cyclic in reality and
|
||||
You can also use the ``acyclic`` pragma for data that is cyclic in reality and
|
||||
then break up the cycles explicitly with ``GC_addCycleRoot``. This can be a
|
||||
very valuable optimization; the Nim compiler itself relies on this
|
||||
very valuable optimization; the Nim compiler itself relies on this
|
||||
optimization trick to improve performance. Note that ``GC_addCycleRoot`` is
|
||||
a quick operation; the root is only registered for the next run of the
|
||||
a quick operation; the root is only registered for the next run of the
|
||||
cycle collector.
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ Realtime support
|
||||
================
|
||||
|
||||
To enable realtime support, the symbol `useRealtimeGC`:idx: needs to be
|
||||
defined via ``--define:useRealtimeGC`` (you can put this into your config
|
||||
defined via ``--define:useRealtimeGC`` (you can put this into your config
|
||||
file as well). With this switch the GC supports the following operations:
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -60,21 +60,21 @@ file as well). With this switch the GC supports the following operations:
|
||||
|
||||
The unit of the parameters ``MaxPauseInUs`` and ``us`` is microseconds.
|
||||
|
||||
These two procs are the two modus operandi of the realtime GC:
|
||||
These two procs are the two modus operandi of the realtime GC:
|
||||
|
||||
(1) GC_SetMaxPause Mode
|
||||
|
||||
You can call ``GC_SetMaxPause`` at program startup and then each triggered
|
||||
GC run tries to not take longer than ``MaxPause`` time. However, it is
|
||||
possible (and common) that the work is nevertheless not evenly distributed
|
||||
as each call to ``new`` can trigger the GC and thus take ``MaxPause``
|
||||
GC run tries to not take longer than ``MaxPause`` time. However, it is
|
||||
possible (and common) that the work is nevertheless not evenly distributed
|
||||
as each call to ``new`` can trigger the GC and thus take ``MaxPause``
|
||||
time.
|
||||
|
||||
(2) GC_step Mode
|
||||
|
||||
This allows the GC to perform some work for up to ``us`` time. This is
|
||||
useful to call in a main loop to ensure the GC can do its work. To
|
||||
bind all GC activity to a ``GC_step`` call, deactivate the GC with
|
||||
useful to call in a main loop to ensure the GC can do its work. To
|
||||
bind all GC activity to a ``GC_step`` call, deactivate the GC with
|
||||
``GC_disable`` at program startup.
|
||||
|
||||
These procs provide a "best effort" realtime guarantee; in particular the
|
||||
@@ -87,7 +87,7 @@ is triggered.
|
||||
Time measurement
|
||||
----------------
|
||||
|
||||
The GC's way of measuring 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.
|
||||
@@ -95,7 +95,7 @@ implementation):
|
||||
3) ``gettimeofday`` on Posix systems.
|
||||
|
||||
As such it supports a resolution of nanoseconds internally; however the API
|
||||
uses microseconds for convenience.
|
||||
uses microseconds for convenience.
|
||||
|
||||
|
||||
Define the symbol ``reportMissedDeadlines`` to make the GC output whenever it
|
||||
@@ -106,7 +106,7 @@ later versions of the collector.
|
||||
Tweaking the GC
|
||||
---------------
|
||||
|
||||
The collector checks whether there is still time left for its work after
|
||||
The collector checks whether there is still time left for its work after
|
||||
every ``workPackage``'th iteration. This is currently set to 100 which means
|
||||
that up to 100 objects are traversed and freed before it checks again. Thus
|
||||
``workPackage`` affects the timing granularity and may need to be tweaked in
|
||||
|
||||
@@ -22,8 +22,8 @@ Path Purpose
|
||||
``bin`` generated binary files
|
||||
``build`` generated C code for the installation
|
||||
``compiler`` the Nim compiler itself; note that this
|
||||
code has been translated from a bootstrapping
|
||||
version written in Pascal, so the code is **not**
|
||||
code has been translated from a bootstrapping
|
||||
version written in Pascal, so the code is **not**
|
||||
a poster child of good Nim code
|
||||
``config`` configuration files for Nim
|
||||
``dist`` additional packages for the distribution
|
||||
@@ -38,8 +38,8 @@ Path Purpose
|
||||
Bootstrapping the compiler
|
||||
==========================
|
||||
|
||||
As of version 0.8.5 the compiler is maintained in Nim. (The first versions
|
||||
have been implemented in Object Pascal.) The Python-based build system has
|
||||
As of version 0.8.5 the compiler is maintained in Nim. (The first versions
|
||||
have been implemented in Object Pascal.) The Python-based build system has
|
||||
been rewritten in Nim too.
|
||||
|
||||
Compiling the compiler is a simple matter of running::
|
||||
@@ -121,7 +121,7 @@ Look at the file ``lib/system/hti.nim`` for more information.
|
||||
Debugging the compiler
|
||||
======================
|
||||
|
||||
You can of course use GDB or Visual Studio to debug the
|
||||
You can of course use GDB or Visual Studio to debug the
|
||||
compiler (via ``--debuginfo --lineDir:on``). However, there
|
||||
are also lots of procs that aid in debugging:
|
||||
|
||||
@@ -180,7 +180,7 @@ children. Types and symbols are represented by other nodes, because they
|
||||
may contain cycles. The AST changes its shape after semantic checking. This
|
||||
is needed to make life easier for the code generators. See the "ast" module
|
||||
for the type definitions. The `macros <macros.html>`_ module contains many
|
||||
examples how the AST represents each syntactic structure.
|
||||
examples how the AST represents each syntactic structure.
|
||||
|
||||
|
||||
How the RTL is compiled
|
||||
@@ -202,7 +202,7 @@ Compilation cache
|
||||
=================
|
||||
|
||||
The implementation of the compilation cache is tricky: There are lots
|
||||
of issues to be solved for the front- and backend. In the following
|
||||
of issues to be solved for the front- and backend. In the following
|
||||
sections *global* means *shared between modules* or *property of the whole
|
||||
program*.
|
||||
|
||||
@@ -214,31 +214,31 @@ Methods and type converters
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Nim contains language features that are *global*. The best example for that
|
||||
are multi methods: Introducing a new method with the same name and some
|
||||
are multi methods: Introducing a new method with the same name and some
|
||||
compatible object parameter means that the method's dispatcher needs to take
|
||||
the new method into account. So the dispatching logic is only completely known
|
||||
after the whole program has been translated!
|
||||
|
||||
Other features that are *implicitly* triggered cause problems for modularity
|
||||
Other features that are *implicitly* triggered cause problems for modularity
|
||||
too. Type converters fall into this category:
|
||||
|
||||
.. code-block:: nim
|
||||
# module A
|
||||
converter toBool(x: int): bool =
|
||||
result = x != 0
|
||||
|
||||
|
||||
.. code-block:: nim
|
||||
# module B
|
||||
import A
|
||||
|
||||
|
||||
if 1:
|
||||
echo "ugly, but should work"
|
||||
|
||||
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`` *explicitly*.
|
||||
in ``B`` *explicitly*.
|
||||
|
||||
Both the multi method and the type converter problems are solved by storing
|
||||
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*
|
||||
when the ROD file is read.
|
||||
|
||||
@@ -266,7 +266,7 @@ Backend issues
|
||||
- Emulated thread vars are global.
|
||||
|
||||
|
||||
However the biggest problem is that dead code elimination breaks modularity!
|
||||
However the biggest problem is that dead code elimination breaks modularity!
|
||||
To see why, consider this scenario: The module ``G`` (for example the huge
|
||||
Gtk2 module...) is compiled with dead code elimination turned on. So none
|
||||
of ``G``'s procs is generated at all.
|
||||
@@ -274,13 +274,13 @@ of ``G``'s procs is generated at all.
|
||||
Then module ``B`` is compiled that requires ``G.P1``. Ok, no problem,
|
||||
``G.P1`` is loaded from the symbol file and ``G.c`` now contains ``G.P1``.
|
||||
|
||||
Then module ``A`` (that depends onto ``B`` and ``G``) is compiled and ``B``
|
||||
Then module ``A`` (that depends onto ``B`` and ``G``) is compiled and ``B``
|
||||
and ``G`` are left unchanged. ``A`` requires ``G.P2``.
|
||||
|
||||
So now ``G.c`` MUST contain both ``P1`` and ``P2``, but we haven't even
|
||||
loaded ``P1`` from the symbol file, nor do we want to because we then quickly
|
||||
would restore large parts of the whole program. But we also don't want to
|
||||
store ``P1`` in ``B.c`` because that would mean to store every symbol where
|
||||
So now ``G.c`` MUST contain both ``P1`` and ``P2``, but we haven't even
|
||||
loaded ``P1`` from the symbol file, nor do we want to because we then quickly
|
||||
would restore large parts of the whole program. But we also don't want to
|
||||
store ``P1`` in ``B.c`` because that would mean to store every symbol where
|
||||
it is referred from which ultimately means the main module and putting
|
||||
everything in a single C file.
|
||||
|
||||
@@ -290,7 +290,7 @@ that is implemented in the C code generator (have a look at the ``ccgmerge``
|
||||
module). The merging may lead to *cruft* (aka dead code) in generated C code
|
||||
which can only be removed by recompiling a project with the compilation cache
|
||||
turned off. Nevertheless the merge solution is way superior to the
|
||||
cheap solution "turn off dead code elimination if the compilation cache is
|
||||
cheap solution "turn off dead code elimination if the compilation cache is
|
||||
turned on".
|
||||
|
||||
|
||||
@@ -394,7 +394,7 @@ Consider this example:
|
||||
# r is on the stack
|
||||
setRef(r.left) # here we should update the refcounts!
|
||||
|
||||
We have to decide at runtime whether the reference is on the stack or not.
|
||||
We have to decide at runtime whether the reference is on the stack or not.
|
||||
The generated code looks roughly like this:
|
||||
|
||||
.. code-block:: C
|
||||
@@ -422,7 +422,7 @@ Design
|
||||
A ``closure`` proc var can call ordinary procs of the default Nim calling
|
||||
convention. But not the other way round! A closure is implemented as a
|
||||
``tuple[prc, env]``. ``env`` can be nil implying a call without a closure.
|
||||
This means that a call through a closure generates an ``if`` but the
|
||||
This means that a call through a closure generates an ``if`` but the
|
||||
interoperability is worth the cost of the ``if``. Thunk generation would be
|
||||
possible too, but it's slightly more effort to implement.
|
||||
|
||||
@@ -430,7 +430,7 @@ Tests with GCC on Amd64 showed that it's really beneficical if the
|
||||
'environment' pointer is passed as the last argument, not as the first argument.
|
||||
|
||||
Proper thunk generation is harder because the proc that is to wrap
|
||||
could stem from a complex expression:
|
||||
could stem from a complex expression:
|
||||
|
||||
.. code-block:: nim
|
||||
receivesClosure(returnsDefaultCC[i])
|
||||
@@ -438,15 +438,15 @@ could stem from a complex expression:
|
||||
A thunk would need to call 'returnsDefaultCC[i]' somehow and that would require
|
||||
an *additional* closure generation... Ok, not really, but it requires to pass
|
||||
the function to call. So we'd end up with 2 indirect calls instead of one.
|
||||
Another much more severe problem which this solution is that it's not GC-safe
|
||||
Another much more severe problem which this solution is that it's not GC-safe
|
||||
to pass a proc pointer around via a generic ``ref`` type.
|
||||
|
||||
|
||||
Example code:
|
||||
|
||||
.. code-block:: nim
|
||||
proc add(x: int): proc (y: int): int {.closure.} =
|
||||
return proc (y: int): int =
|
||||
proc add(x: int): proc (y: int): int {.closure.} =
|
||||
return proc (y: int): int =
|
||||
return x + y
|
||||
|
||||
var add2 = add(2)
|
||||
@@ -458,16 +458,16 @@ This should produce roughly this code:
|
||||
type
|
||||
PEnv = ref object
|
||||
x: int # data
|
||||
|
||||
proc anon(y: int, c: PClosure): int =
|
||||
|
||||
proc anon(y: int, c: PClosure): int =
|
||||
return y + c.x
|
||||
|
||||
|
||||
proc add(x: int): tuple[prc, data] =
|
||||
var env: PEnv
|
||||
new env
|
||||
env.x = x
|
||||
result = (anon, env)
|
||||
|
||||
|
||||
var add2 = add(2)
|
||||
let tmp = if add2.data == nil: add2.prc(5) else: add2.prc(5, add2.data)
|
||||
echo tmp
|
||||
@@ -476,9 +476,9 @@ This should produce roughly this code:
|
||||
Beware of nesting:
|
||||
|
||||
.. code-block:: nim
|
||||
proc add(x: int): proc (y: int): proc (z: int): int {.closure.} {.closure.} =
|
||||
return lamba (y: int): proc (z: int): int {.closure.} =
|
||||
return lambda (z: int): int =
|
||||
proc add(x: int): proc (y: int): proc (z: int): int {.closure.} {.closure.} =
|
||||
return lamba (y: int): proc (z: int): int {.closure.} =
|
||||
return lambda (z: int): int =
|
||||
return x + y + z
|
||||
|
||||
var add24 = add(2)(4)
|
||||
@@ -490,26 +490,26 @@ This should produce roughly this code:
|
||||
type
|
||||
PEnvX = ref object
|
||||
x: int # data
|
||||
|
||||
|
||||
PEnvY = ref object
|
||||
y: int
|
||||
ex: PEnvX
|
||||
|
||||
|
||||
proc lambdaZ(z: int, ey: PEnvY): int =
|
||||
return ey.ex.x + ey.y + z
|
||||
|
||||
|
||||
proc lambdaY(y: int, ex: PEnvX): tuple[prc, data: PEnvY] =
|
||||
var ey: PEnvY
|
||||
new ey
|
||||
ey.y = y
|
||||
ey.ex = ex
|
||||
result = (lambdaZ, ey)
|
||||
|
||||
|
||||
proc add(x: int): tuple[prc, data: PEnvX] =
|
||||
var ex: PEnvX
|
||||
ex.x = x
|
||||
result = (labmdaY, ex)
|
||||
|
||||
|
||||
var tmp = add(2)
|
||||
var tmp2 = tmp.fn(4, tmp.data)
|
||||
var add24 = tmp2.fn(4, tmp2.data)
|
||||
@@ -517,14 +517,14 @@ This should produce roughly this code:
|
||||
|
||||
|
||||
We could get rid of nesting environments by always inlining inner anon procs.
|
||||
More useful is escape analysis and stack allocation of the environment,
|
||||
More useful is escape analysis and stack allocation of the environment,
|
||||
however.
|
||||
|
||||
|
||||
Alternative
|
||||
-----------
|
||||
|
||||
Process the closure of all inner procs in one pass and accumulate the
|
||||
Process the closure of all inner procs in one pass and accumulate the
|
||||
environments. This is however not always possible.
|
||||
|
||||
|
||||
@@ -532,21 +532,21 @@ Accumulator
|
||||
-----------
|
||||
|
||||
.. code-block:: nim
|
||||
proc getAccumulator(start: int): proc (): int {.closure} =
|
||||
proc getAccumulator(start: int): proc (): int {.closure} =
|
||||
var i = start
|
||||
return lambda: int =
|
||||
return lambda: int =
|
||||
inc i
|
||||
return i
|
||||
|
||||
|
||||
proc p =
|
||||
var delta = 7
|
||||
proc accumulator(start: int): proc(): int =
|
||||
var x = start-1
|
||||
result = proc (): int =
|
||||
result = proc (): int =
|
||||
x = x + delta
|
||||
inc delta
|
||||
return x
|
||||
|
||||
|
||||
var a = accumulator(3)
|
||||
var b = accumulator(4)
|
||||
echo a() + b()
|
||||
@@ -560,7 +560,7 @@ pass generates code to setup the environment and to pass it around. However,
|
||||
this pass does not change the types! So we have some kind of mismatch here; on
|
||||
the one hand the proc expression becomes an explicit tuple, on the other hand
|
||||
the tyProc(ccClosure) type is not changed. For C code generation it's also
|
||||
important the hidden formal param is ``void*`` and not something more
|
||||
important the hidden formal param is ``void*`` and not something more
|
||||
specialized. However the more specialized env type needs to passed to the
|
||||
backend somehow. We deal with this by modifying ``s.ast[paramPos]`` to contain
|
||||
the formal hidden parameter, but not ``s.typ``!
|
||||
|
||||
@@ -14,20 +14,20 @@ optional *a*. Parentheses may be used to group elements.
|
||||
``&`` is the lookahead operator; ``&a`` means that an ``a`` is expected but
|
||||
not consumed. It will be consumed in the following rule.
|
||||
|
||||
The ``|``, ``/`` symbols are used to mark alternatives and have the lowest
|
||||
precedence. ``/`` is the ordered choice that requires the parser to try the
|
||||
The ``|``, ``/`` symbols are used to mark alternatives and have the lowest
|
||||
precedence. ``/`` is the ordered choice that requires the parser to try the
|
||||
alternatives in the given order. ``/`` is often used to ensure the grammar
|
||||
is not ambiguous.
|
||||
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::
|
||||
|
||||
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)*``
|
||||
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::
|
||||
|
||||
arrayConstructor = '[' expr ^* ',' ']'
|
||||
|
||||
@@ -26,9 +26,9 @@ program execution. Unless explicitly classified, an error is a static error.
|
||||
|
||||
A `checked runtime error`:idx: is an error that the implementation detects
|
||||
and reports at runtime. The method for reporting such errors is via *raising
|
||||
exceptions* or *dying with a fatal error*. However, the implementation
|
||||
exceptions* or *dying with a fatal error*. However, the implementation
|
||||
provides a means to disable these runtime checks. See the section pragmas_
|
||||
for details.
|
||||
for details.
|
||||
|
||||
Whether a checked runtime error results in an exception or in a fatal error at
|
||||
runtime is implementation specific. Thus the following program is always
|
||||
|
||||
@@ -5,7 +5,7 @@ Exception tracking
|
||||
------------------
|
||||
|
||||
Nim supports exception tracking. The `raises`:idx: pragma can be used
|
||||
to explicitly define which exceptions a proc/iterator/method/converter is
|
||||
to explicitly define which exceptions a proc/iterator/method/converter is
|
||||
allowed to raise. The compiler verifies this:
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -24,7 +24,7 @@ An empty ``raises`` list (``raises: []``) means that no exception may be raised:
|
||||
result = false
|
||||
|
||||
|
||||
A ``raises`` list can also be attached to a proc type. This affects type
|
||||
A ``raises`` list can also be attached to a proc type. This affects type
|
||||
compatibility:
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -35,7 +35,7 @@ compatibility:
|
||||
|
||||
proc p(x: string) =
|
||||
raise newException(OSError, "OS")
|
||||
|
||||
|
||||
c = p # type error
|
||||
|
||||
|
||||
@@ -46,30 +46,30 @@ possibly raised exceptions; the algorithm operates on ``p``'s call graph:
|
||||
raise ``system.Exception`` (the base type of the exception hierarchy) and
|
||||
thus any exception unless ``T`` has an explicit ``raises`` list.
|
||||
However if the call is of the form ``f(...)`` where ``f`` is a parameter
|
||||
of the currently analysed routine it is ignored. The call is optimistically
|
||||
of the currently analysed routine it is ignored. The call is optimistically
|
||||
assumed to have no effect. Rule 2 compensates for this case.
|
||||
2. Every expression of some proc type within a call that is not a call
|
||||
itself (and not nil) is assumed to be called indirectly somehow and thus
|
||||
2. Every expression of some proc type within a call that is not a call
|
||||
itself (and not nil) is assumed to be called indirectly somehow and thus
|
||||
its raises list is added to ``p``'s raises list.
|
||||
3. Every call to a proc ``q`` which has an unknown body (due to a forward
|
||||
declaration or an ``importc`` pragma) is assumed to
|
||||
3. Every call to a proc ``q`` which has an unknown body (due to a forward
|
||||
declaration or an ``importc`` pragma) is assumed to
|
||||
raise ``system.Exception`` unless ``q`` has an explicit ``raises`` list.
|
||||
4. Every call to a method ``m`` is assumed to
|
||||
4. Every call to a method ``m`` is assumed to
|
||||
raise ``system.Exception`` unless ``m`` has an explicit ``raises`` list.
|
||||
5. For every other call the analysis can determine an exact ``raises`` list.
|
||||
6. For determining a ``raises`` list, the ``raise`` and ``try`` statements
|
||||
6. For determining a ``raises`` list, the ``raise`` and ``try`` statements
|
||||
of ``p`` are taken into consideration.
|
||||
|
||||
Rules 1-2 ensure the following works:
|
||||
Rules 1-2 ensure the following works:
|
||||
|
||||
.. code-block:: nim
|
||||
proc noRaise(x: proc()) {.raises: [].} =
|
||||
# unknown call that might raise anything, but valid:
|
||||
x()
|
||||
|
||||
|
||||
proc doRaise() {.raises: [IOError].} =
|
||||
raise newException(IOError, "IO")
|
||||
|
||||
|
||||
proc use() {.raises: [].} =
|
||||
# doesn't compile! Can raise IOError!
|
||||
noRaise(doRaise)
|
||||
@@ -82,21 +82,21 @@ Tag tracking
|
||||
------------
|
||||
|
||||
The exception tracking is part of Nim's `effect system`:idx:. Raising an
|
||||
exception is an *effect*. Other effects can also be defined. A user defined
|
||||
exception is an *effect*. Other effects can also be defined. A user defined
|
||||
effect is a means to *tag* a routine and to perform checks against this tag:
|
||||
|
||||
.. code-block:: nim
|
||||
type IO = object ## input/output effect
|
||||
proc readLine(): string {.tags: [IO].}
|
||||
|
||||
|
||||
proc no_IO_please() {.tags: [].} =
|
||||
# the compiler prevents this:
|
||||
let x = readLine()
|
||||
|
||||
A tag has to be a type name. A ``tags`` list - like a ``raises`` list - can
|
||||
A tag has to be a type name. A ``tags`` list - like a ``raises`` list - can
|
||||
also be attached to a proc type. This affects type compatibility.
|
||||
|
||||
The inference for tag tracking is analogous to the inference for
|
||||
The inference for tag tracking is analogous to the inference for
|
||||
exception tracking.
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ Read/Write tracking
|
||||
|
||||
**Note**: Read/write tracking is not yet implemented!
|
||||
|
||||
The inference for read/write tracking is analogous to the inference for
|
||||
The inference for read/write tracking is analogous to the inference for
|
||||
exception tracking.
|
||||
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ 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``). Note this behavior is
|
||||
``distinct auto`` type class (also known as ``any``). Note this behavior is
|
||||
deprecated for procs; templates, however, support them:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
@@ -36,7 +36,7 @@ With this notation we can now easily define the core of the grammar: A block of
|
||||
statements (simplified example)::
|
||||
|
||||
ifStmt = 'if' expr ':' stmt
|
||||
(IND{=} 'elif' expr ':' stmt)*
|
||||
(IND{=} 'elif' expr ':' stmt)*
|
||||
(IND{=} 'else' ':' stmt)?
|
||||
|
||||
simpleStmt = ifStmt / ...
|
||||
@@ -156,7 +156,7 @@ contain the following `escape sequences`:idx:\ :
|
||||
================== ===================================================
|
||||
|
||||
|
||||
Strings in Nim may contain any 8-bit value, even embedded zeros. However
|
||||
Strings in Nim may contain any 8-bit value, even embedded zeros. However
|
||||
some operations may interpret the first binary zero as a terminator.
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ be whitespace between the opening ``"""`` and the newline),
|
||||
the newline (and the preceding whitespace) is not included in the string. The
|
||||
ending of the string literal is defined by the pattern ``"""[^"]``, so this:
|
||||
|
||||
.. code-block:: nim
|
||||
.. code-block:: nim
|
||||
""""long string within quotes""""
|
||||
|
||||
Produces::
|
||||
@@ -187,9 +187,9 @@ Raw string literals
|
||||
|
||||
Terminal symbol in the grammar: ``RSTR_LIT``.
|
||||
|
||||
There are also raw string literals that are preceded with the
|
||||
letter ``r`` (or ``R``) and are delimited by matching double quotes (just
|
||||
like ordinary string literals) and do not interpret the escape sequences.
|
||||
There are also raw string literals that are preceded with the
|
||||
letter ``r`` (or ``R``) and are delimited by matching double quotes (just
|
||||
like ordinary string literals) and do not interpret the escape sequences.
|
||||
This is especially convenient for regular expressions or Windows paths:
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -201,21 +201,21 @@ To produce a single ``"`` within a raw string literal, it has to be doubled:
|
||||
.. code-block:: nim
|
||||
|
||||
r"a""b"
|
||||
|
||||
|
||||
Produces::
|
||||
|
||||
|
||||
a"b
|
||||
|
||||
``r""""`` is not possible with this notation, because the three leading
|
||||
quotes introduce a triple quoted string literal. ``r"""`` is the same
|
||||
as ``"""`` since triple quoted string literals do not interpret escape
|
||||
``r""""`` is not possible with this notation, because the three leading
|
||||
quotes introduce a triple quoted string literal. ``r"""`` is the same
|
||||
as ``"""`` since triple quoted string literals do not interpret escape
|
||||
sequences either.
|
||||
|
||||
|
||||
Generalized raw string literals
|
||||
-------------------------------
|
||||
|
||||
Terminal symbols in the grammar: ``GENERALIZED_STR_LIT``,
|
||||
Terminal symbols in the grammar: ``GENERALIZED_STR_LIT``,
|
||||
``GENERALIZED_TRIPLESTR_LIT``.
|
||||
|
||||
The construct ``identifier"string literal"`` (without whitespace between the
|
||||
@@ -281,7 +281,7 @@ Numerical constants are of a single type and have the form::
|
||||
DEC_LIT = digit ( ['_'] digit )*
|
||||
OCT_LIT = '0' ('o' | 'c' | 'C') octdigit ( ['_'] octdigit )*
|
||||
BIN_LIT = '0' ('b' | 'B' ) bindigit ( ['_'] bindigit )*
|
||||
|
||||
|
||||
INT_LIT = HEX_LIT
|
||||
| DEC_LIT
|
||||
| OCT_LIT
|
||||
@@ -383,7 +383,7 @@ The following strings denote other tokens::
|
||||
` ( ) { } [ ] , ; [. .] {. .} (. .)
|
||||
|
||||
|
||||
The `slice`:idx: operator `..`:tok: takes precedence over other tokens that
|
||||
contain a dot: `{..}`:tok: are the three tokens `{`:tok:, `..`:tok:, `}`:tok:
|
||||
The `slice`:idx: operator `..`:tok: takes precedence over other tokens that
|
||||
contain a dot: `{..}`:tok: are the three tokens `{`:tok:, `..`:tok:, `}`:tok:
|
||||
and not the two tokens `{.`:tok:, `.}`:tok:.
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ model low level lockfree mechanisms:
|
||||
.. code-block:: nim
|
||||
var dummyLock {.compileTime.}: int
|
||||
var atomicCounter {.guard: dummyLock.}: int
|
||||
|
||||
|
||||
template atomicRead(x): expr =
|
||||
{.locks: [dummyLock].}:
|
||||
memoryReadBarrier()
|
||||
@@ -135,30 +135,30 @@ Lock levels are used to enforce a global locking order in order to prevent
|
||||
deadlocks at compile-time. A lock level is an constant integer in the range
|
||||
0..1_000. Lock level 0 means that no lock is acquired at all.
|
||||
|
||||
If a section of code holds a lock of level ``M`` than it can also acquire any
|
||||
If a section of code holds a lock of level ``M`` than it can also acquire any
|
||||
lock of level ``N < M``. Another lock of level ``M`` cannot be acquired. Locks
|
||||
of the same level can only be acquired *at the same time* within a
|
||||
of the same level can only be acquired *at the same time* within a
|
||||
single ``locks`` section:
|
||||
|
||||
.. code-block:: nim
|
||||
var a, b: TLock[2]
|
||||
var x: TLock[1]
|
||||
# invalid locking order: TLock[1] cannot be acquired before TLock[2]:
|
||||
{.locks: [x].}:
|
||||
{.locks: [x].}:
|
||||
{.locks: [a].}:
|
||||
...
|
||||
# valid locking order: TLock[2] acquired before TLock[1]:
|
||||
{.locks: [a].}:
|
||||
{.locks: [a].}:
|
||||
{.locks: [x].}:
|
||||
...
|
||||
|
||||
# invalid locking order: TLock[2] acquired before TLock[2]:
|
||||
{.locks: [a].}:
|
||||
{.locks: [a].}:
|
||||
{.locks: [b].}:
|
||||
...
|
||||
|
||||
# valid locking order, locks of the same level acquired at the same time:
|
||||
{.locks: [a, b].}:
|
||||
{.locks: [a, b].}:
|
||||
...
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ level. This then means that the routine may acquire locks of up to this level.
|
||||
This is essential so that procs can be called within a ``locks`` section:
|
||||
|
||||
.. code-block:: nim
|
||||
proc p() {.locks: 3.} = discard
|
||||
proc p() {.locks: 3.} = discard
|
||||
|
||||
var a: TLock[4]
|
||||
{.locks: [a].}:
|
||||
@@ -195,6 +195,6 @@ This is essential so that procs can be called within a ``locks`` section:
|
||||
p()
|
||||
|
||||
|
||||
As usual ``locks`` is an inferred effect and there is a subtype
|
||||
As usual ``locks`` is an inferred effect and there is a subtype
|
||||
relation: ``proc () {.locks: N.}`` is a subtype of ``proc () {.locks: M.}``
|
||||
iff (M <= N).
|
||||
|
||||
@@ -81,8 +81,8 @@ A module alias can be introduced via the ``as`` keyword:
|
||||
|
||||
echo su.format("$1", "lalelu")
|
||||
|
||||
The original module name is then not accessible. The
|
||||
notations ``path/to/module`` or ``path.to.module`` or ``"path/to/module"``
|
||||
The original module name is then not accessible. The
|
||||
notations ``path/to/module`` or ``path.to.module`` or ``"path/to/module"``
|
||||
can be used to refer to a module in subdirectories:
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -104,7 +104,7 @@ Likewise the following does not make sense as the name is ``strutils`` already:
|
||||
From import statement
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
After the ``from`` statement a module name follows followed by
|
||||
After the ``from`` statement a module name follows followed by
|
||||
an ``import`` to list the symbols one likes to use without explict
|
||||
full qualification:
|
||||
|
||||
@@ -115,8 +115,8 @@ full qualification:
|
||||
# always possible: full qualification:
|
||||
echo strutils.replace("abc", "a", "z")
|
||||
|
||||
It's also possible to use ``from module import nil`` if one wants to import
|
||||
the module but wants to enforce fully qualified access to every symbol
|
||||
It's also possible to use ``from module import nil`` if one wants to import
|
||||
the module but wants to enforce fully qualified access to every symbol
|
||||
in ``module``.
|
||||
|
||||
|
||||
@@ -134,15 +134,15 @@ modules don't need to import a module's dependencies:
|
||||
# module A
|
||||
import B
|
||||
export B.MyObject
|
||||
|
||||
|
||||
proc `$`*(x: MyObject): string = "my object"
|
||||
|
||||
|
||||
.. code-block:: nim
|
||||
# module C
|
||||
import A
|
||||
|
||||
# B.MyObject has been imported implicitly here:
|
||||
|
||||
# B.MyObject has been imported implicitly here:
|
||||
var x: MyObject
|
||||
echo($x)
|
||||
|
||||
@@ -185,7 +185,7 @@ following places:
|
||||
Module scope
|
||||
~~~~~~~~~~~~
|
||||
All identifiers of a module are valid from the point of declaration until
|
||||
the end of the module. Identifiers from indirectly dependent modules are *not*
|
||||
the end of the module. Identifiers from indirectly dependent modules are *not*
|
||||
available. The `system`:idx: module is automatically imported in every module.
|
||||
|
||||
If a module imports an identifier by two different modules, each occurrence of
|
||||
|
||||
@@ -120,7 +120,7 @@ current module:
|
||||
Method call syntax
|
||||
------------------
|
||||
|
||||
For object oriented programming, the syntax ``obj.method(args)`` can be used
|
||||
For object oriented programming, the syntax ``obj.method(args)`` can be used
|
||||
instead of ``method(obj, args)``. The parentheses can be omitted if there are no
|
||||
remaining arguments: ``obj.len`` (instead of ``len(obj)``).
|
||||
|
||||
@@ -128,7 +128,7 @@ This method call syntax is not restricted to objects, it can be used
|
||||
to supply any type of first argument for procedures:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
|
||||
echo("abc".len) # is the same as echo(len("abc"))
|
||||
echo("abc".toUpper())
|
||||
echo({'a', 'b', 'c'}.card)
|
||||
@@ -143,11 +143,11 @@ See also: `Limitations of the method call syntax`_.
|
||||
Properties
|
||||
----------
|
||||
Nim has no need for *get-properties*: Ordinary get-procedures that are called
|
||||
with the *method call syntax* achieve the same. But setting a value is
|
||||
with the *method call syntax* achieve the same. But setting a value is
|
||||
different; for this a special setter syntax is needed:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
|
||||
type
|
||||
Socket* = ref object of RootObj
|
||||
FHost: int # cannot be accessed from the outside of the module
|
||||
@@ -157,7 +157,7 @@ different; for this a special setter syntax is needed:
|
||||
proc `host=`*(s: var Socket, value: int) {.inline.} =
|
||||
## setter of hostAddr
|
||||
s.FHost = value
|
||||
|
||||
|
||||
proc host*(s: Socket): int {.inline.} =
|
||||
## getter of hostAddr
|
||||
s.FHost
|
||||
@@ -180,18 +180,18 @@ more argument in this case:
|
||||
.. code-block:: nim
|
||||
proc optarg(x: int, y: int = 0): int = x + y
|
||||
proc singlearg(x: int): int = 20*x
|
||||
|
||||
|
||||
echo optarg 1, " ", singlearg 2 # prints "1 40"
|
||||
|
||||
|
||||
let fail = optarg 1, optarg 8 # Wrong. Too many arguments for a command call
|
||||
let x = optarg(1, optarg 8) # traditional procedure call with 2 arguments
|
||||
let y = 1.optarg optarg 8 # same thing as above, w/o the parenthesis
|
||||
assert x == y
|
||||
|
||||
The command invocation syntax also can't have complex expressions as arguments.
|
||||
For example: (`anonymous procs`_), ``if``, ``case`` or ``try``. The (`do
|
||||
notation`_) is limited, but usable for a single proc (see the example in the
|
||||
corresponding section). Function calls with no arguments still needs () to
|
||||
The command invocation syntax also can't have complex expressions as arguments.
|
||||
For example: (`anonymous procs`_), ``if``, ``case`` or ``try``. The (`do
|
||||
notation`_) is limited, but usable for a single proc (see the example in the
|
||||
corresponding section). Function calls with no arguments still needs () to
|
||||
distinguish between a call and the function itself as a first class value.
|
||||
|
||||
|
||||
@@ -221,7 +221,7 @@ the proc's name.
|
||||
cmp(x.len, y.len))
|
||||
|
||||
|
||||
Procs as expressions can appear both as nested procs and inside top level
|
||||
Procs as expressions can appear both as nested procs and inside top level
|
||||
executable code.
|
||||
|
||||
|
||||
@@ -237,10 +237,10 @@ calls can use the ``do`` keyword:
|
||||
sort(cities) do (x,y: string) -> int:
|
||||
cmp(x.len, y.len)
|
||||
# Less parenthesis using the method plus command syntax:
|
||||
cities = cities.map do (x:string) -> string:
|
||||
cities = cities.map do (x:string) -> string:
|
||||
"City of " & x
|
||||
|
||||
``do`` is written after the parentheses enclosing the regular proc params.
|
||||
``do`` is written after the parentheses enclosing the regular proc params.
|
||||
The proc expression represented by the do block is appended to them.
|
||||
|
||||
More than one ``do`` block can appear in a single call:
|
||||
@@ -261,11 +261,11 @@ Nonoverloadable builtins
|
||||
The following builtin procs cannot be overloaded for reasons of implementation
|
||||
simplicity (they require specialized semantic checking)::
|
||||
|
||||
declared, defined, definedInScope, compiles, low, high, sizeOf,
|
||||
declared, defined, definedInScope, compiles, low, high, sizeOf,
|
||||
is, of, 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
|
||||
Thus they act more like keywords than like ordinary identifiers; unlike a
|
||||
keyword however, a redefinition may `shadow`:idx: the definition in
|
||||
the ``system`` 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``::
|
||||
@@ -342,11 +342,11 @@ returned value is an l-value and can be modified by the caller:
|
||||
|
||||
proc WriteAccessToG(): var int =
|
||||
result = g
|
||||
|
||||
|
||||
WriteAccessToG() = 6
|
||||
assert g == 6
|
||||
|
||||
It is a compile time error if the implicitly introduced pointer could be
|
||||
It is a compile time error if the implicitly introduced pointer could be
|
||||
used to access a location beyond its lifetime:
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -354,7 +354,7 @@ used to access a location beyond its lifetime:
|
||||
var g = 0
|
||||
result = g # Error!
|
||||
|
||||
For iterators, a component of a tuple return type can have a ``var`` type too:
|
||||
For iterators, a component of a tuple return type can have a ``var`` type too:
|
||||
|
||||
.. code-block:: nim
|
||||
iterator mpairs(a: var seq[string]): tuple[key: int, val: var string] =
|
||||
@@ -384,28 +384,28 @@ dispatch.
|
||||
x: int
|
||||
PlusExpr = ref object of Expression
|
||||
a, b: Expression
|
||||
|
||||
|
||||
method eval(e: Expression): int =
|
||||
# override this base method
|
||||
quit "to override!"
|
||||
|
||||
|
||||
method eval(e: Literal): int = return e.x
|
||||
|
||||
|
||||
method eval(e: PlusExpr): int =
|
||||
# watch out: relies on dynamic binding
|
||||
result = eval(e.a) + eval(e.b)
|
||||
|
||||
|
||||
proc newLit(x: int): Literal =
|
||||
new(result)
|
||||
result.x = x
|
||||
|
||||
|
||||
proc newPlus(a, b: Expression): PlusExpr =
|
||||
new(result)
|
||||
result.a = a
|
||||
result.b = b
|
||||
|
||||
echo eval(newPlus(newPlus(newLit(1), newLit(2)), newLit(4)))
|
||||
|
||||
|
||||
In the example the constructors ``newLit`` and ``newPlus`` are procs
|
||||
because they should use static binding, but ``eval`` is a method because it
|
||||
requires dynamic binding.
|
||||
@@ -418,24 +418,24 @@ dispatching:
|
||||
Thing = ref object of RootObj
|
||||
Unit = ref object of Thing
|
||||
x: int
|
||||
|
||||
|
||||
method collide(a, b: Thing) {.inline.} =
|
||||
quit "to override!"
|
||||
|
||||
|
||||
method collide(a: Thing, b: Unit) {.inline.} =
|
||||
echo "1"
|
||||
|
||||
|
||||
method collide(a: Unit, b: Thing) {.inline.} =
|
||||
echo "2"
|
||||
|
||||
|
||||
var a, b: Unit
|
||||
new a
|
||||
new b
|
||||
collide(a, b) # output: 2
|
||||
|
||||
|
||||
Invocation of a multi-method cannot be ambiguous: collide 2 is preferred over
|
||||
collide 1 because the resolution works from left to right.
|
||||
Invocation of a multi-method cannot be ambiguous: collide 2 is preferred over
|
||||
collide 1 because the resolution works from left to right.
|
||||
In the example ``Unit, Thing`` is preferred over ``Thing, Unit``.
|
||||
|
||||
**Performance note**: Nim does not produce a virtual method table, but
|
||||
@@ -450,7 +450,7 @@ Iterators and the for statement
|
||||
The `for`:idx: statement is an abstract mechanism to iterate over the elements
|
||||
of a container. It relies on an `iterator`:idx: to do so. Like ``while``
|
||||
statements, ``for`` statements open an `implicit block`:idx:, so that they
|
||||
can be left with a ``break`` statement.
|
||||
can be left with a ``break`` statement.
|
||||
|
||||
The ``for`` loop declares iteration variables - their scope reaches until the
|
||||
end of the loop body. The iteration variables' types are inferred by the
|
||||
@@ -486,7 +486,7 @@ The compiler generates code as if the programmer would have written this:
|
||||
|
||||
If the iterator yields a tuple, there can be as many iteration variables
|
||||
as there are components in the tuple. The i'th iteration variable's type is
|
||||
the type of the i'th component. In other words, implicit tuple unpacking in a
|
||||
the type of the i'th component. In other words, implicit tuple unpacking in a
|
||||
for loop context is supported.
|
||||
|
||||
Implict items/pairs invocations
|
||||
@@ -498,11 +498,11 @@ ie. an ``items`` iterator is implicitly invoked:
|
||||
|
||||
.. code-block:: nim
|
||||
for x in [1,2,3]: echo x
|
||||
|
||||
|
||||
If the for loop has exactly 2 variables, a ``pairs`` iterator is implicitly
|
||||
invoked.
|
||||
|
||||
Symbol lookup of the identifiers ``items``/``pairs`` is performed after
|
||||
Symbol lookup of the identifiers ``items``/``pairs`` is performed after
|
||||
the rewriting step, so that all overloads of ``items``/``pairs`` are taken
|
||||
into account.
|
||||
|
||||
@@ -511,7 +511,7 @@ First class iterators
|
||||
---------------------
|
||||
|
||||
There are 2 kinds of iterators in Nim: *inline* and *closure* iterators.
|
||||
An `inline iterator`:idx: is an iterator that's always inlined by the compiler
|
||||
An `inline iterator`:idx: is an iterator that's always inlined by the compiler
|
||||
leading to zero overhead for the abstraction, but may result in a heavy
|
||||
increase in code size. Inline iterators are second class citizens;
|
||||
They can be passed as parameters only to other inlining code facilities like
|
||||
@@ -522,7 +522,7 @@ In contrast to that, a `closure iterator`:idx: can be passed around more freely:
|
||||
.. code-block:: nim
|
||||
iterator count0(): int {.closure.} =
|
||||
yield 0
|
||||
|
||||
|
||||
iterator count2(): int {.closure.} =
|
||||
var x = 1
|
||||
yield x
|
||||
@@ -539,7 +539,7 @@ Closure iterators have other restrictions than inline iterators:
|
||||
|
||||
1. ``yield`` in a closure iterator can not occur in a ``try`` statement.
|
||||
2. For now, a closure iterator cannot be evaluated at compile time.
|
||||
3. ``return`` is allowed in a closure iterator (but rarely useful) and ends
|
||||
3. ``return`` is allowed in a closure iterator (but rarely useful) and ends
|
||||
iteration.
|
||||
4. Neither inline nor closure iterators can be recursive.
|
||||
|
||||
@@ -547,7 +547,7 @@ Iterators that are neither marked ``{.closure.}`` nor ``{.inline.}`` explicitly
|
||||
default to being inline, but this may change in future versions of the
|
||||
implementation.
|
||||
|
||||
The ``iterator`` type is always of the calling convention ``closure``
|
||||
The ``iterator`` type is always of the calling convention ``closure``
|
||||
implicitly; the following example shows how to use iterators to implement
|
||||
a `collaborative tasking`:idx: system:
|
||||
|
||||
@@ -650,7 +650,7 @@ parameters of an outer factory proc:
|
||||
Converters
|
||||
==========
|
||||
|
||||
A converter is like an ordinary proc except that it enhances
|
||||
A converter is like an ordinary proc except that it enhances
|
||||
the "implicitly convertible" type relation (see `Convertible relation`_):
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
@@ -34,7 +34,7 @@ templates and macros), depending on the desired effect:
|
||||
The following dot operators are available:
|
||||
|
||||
operator `.`
|
||||
------------
|
||||
------------
|
||||
This operator will be matched against both field accesses and method calls.
|
||||
|
||||
operator `.()`
|
||||
|
||||
@@ -176,8 +176,8 @@ The rules for compile-time computability are:
|
||||
1. Literals are compile-time computable.
|
||||
2. Type conversions are compile-time computable.
|
||||
3. Procedure calls of the form ``p(X)`` are compile-time computable if
|
||||
``p`` is a proc without side-effects (see the `noSideEffect pragma
|
||||
<#pragmas-nosideeffect-pragma>`_ for details) and if ``X`` is a
|
||||
``p`` is a proc without side-effects (see the `noSideEffect pragma
|
||||
<#pragmas-nosideeffect-pragma>`_ for details) and if ``X`` is a
|
||||
(possibly empty) list of compile-time computable arguments.
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
Taint mode
|
||||
==========
|
||||
|
||||
The Nim compiler and most parts of the standard library support
|
||||
a taint mode. Input strings are declared with the `TaintedString`:idx:
|
||||
The Nim compiler and most parts of the standard library support
|
||||
a taint mode. Input strings are declared with the `TaintedString`:idx:
|
||||
string type declared in the ``system`` module.
|
||||
|
||||
If the taint mode is turned on (via the ``--taintMode:on`` command line
|
||||
If the taint mode is turned on (via the ``--taintMode:on`` command line
|
||||
option) it is a distinct string type which helps to detect input
|
||||
validation errors:
|
||||
|
||||
@@ -13,7 +13,7 @@ validation errors:
|
||||
echo "your name: "
|
||||
var name: TaintedString = stdin.readline
|
||||
# it is safe here to output the name without any input validation, so
|
||||
# we simply convert `name` to string to make the compiler happy:
|
||||
# we simply convert `name` to string to make the compiler happy:
|
||||
echo "hi, ", name.string
|
||||
|
||||
If the taint mode is turned off, ``TaintedString`` is simply an alias for
|
||||
|
||||
@@ -16,17 +16,17 @@ Example:
|
||||
|
||||
assert(5 != 6) # the compiler rewrites that to: assert(not (5 == 6))
|
||||
|
||||
The ``!=``, ``>``, ``>=``, ``in``, ``notin``, ``isnot`` operators are in fact
|
||||
The ``!=``, ``>``, ``>=``, ``in``, ``notin``, ``isnot`` operators are in fact
|
||||
templates:
|
||||
|
||||
| ``a > b`` is transformed into ``b < a``.
|
||||
| ``a in b`` is transformed into ``contains(b, a)``.
|
||||
| ``a in b`` is transformed into ``contains(b, a)``.
|
||||
| ``notin`` and ``isnot`` have the obvious meanings.
|
||||
|
||||
The "types" of templates can be the symbols ``expr`` (stands for *expression*),
|
||||
``stmt`` (stands for *statement*) or ``typedesc`` (stands for *type
|
||||
description*). These are "meta types", they can only be used in certain
|
||||
contexts. Real types can be used too; this implies that expressions are
|
||||
The "types" of templates can be the symbols ``expr`` (stands for *expression*),
|
||||
``stmt`` (stands for *statement*) or ``typedesc`` (stands for *type
|
||||
description*). These are "meta types", they can only be used in certain
|
||||
contexts. Real types can be used too; this implies that expressions are
|
||||
expected.
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ So ordinary templates cannot receive undeclared identifiers:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
template declareInt(x: expr) =
|
||||
template declareInt(x: expr) =
|
||||
var x: int
|
||||
|
||||
declareInt(x) # error: unknown identifier: 'x'
|
||||
@@ -51,7 +51,7 @@ receive undeclared identifiers:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
template declareInt(x: expr) {.immediate.} =
|
||||
template declareInt(x: expr) {.immediate.} =
|
||||
var x: int
|
||||
|
||||
declareInt(x) # valid
|
||||
@@ -75,11 +75,11 @@ special ``:`` syntax:
|
||||
close(f)
|
||||
else:
|
||||
quit("cannot open: " & fn)
|
||||
|
||||
|
||||
withFile(txt, "ttempl3.txt", fmWrite):
|
||||
txt.writeLine("line 1")
|
||||
txt.writeLine("line 2")
|
||||
|
||||
|
||||
In the example the two ``writeLine`` statements are bound to the ``actions``
|
||||
parameter.
|
||||
|
||||
@@ -92,9 +92,9 @@ bound from the definition scope of the template:
|
||||
|
||||
.. code-block:: nim
|
||||
# Module A
|
||||
var
|
||||
var
|
||||
lastId = 0
|
||||
|
||||
|
||||
template genId*: expr =
|
||||
inc(lastId)
|
||||
lastId
|
||||
@@ -102,10 +102,10 @@ bound from the definition scope of the template:
|
||||
.. code-block:: nim
|
||||
# Module B
|
||||
import A
|
||||
|
||||
|
||||
echo genId() # Works as 'lastId' has been bound in 'genId's defining scope
|
||||
|
||||
As in generics symbol binding can be influenced via ``mixin`` or ``bind``
|
||||
As in generics symbol binding can be influenced via ``mixin`` or ``bind``
|
||||
statements.
|
||||
|
||||
|
||||
@@ -117,11 +117,11 @@ In templates identifiers can be constructed with the backticks notation:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
template typedef(name: expr, typ: typedesc) {.immediate.} =
|
||||
template typedef(name: expr, typ: typedesc) {.immediate.} =
|
||||
type
|
||||
`T name`* {.inject.} = typ
|
||||
`P name`* {.inject.} = ref `T name`
|
||||
|
||||
|
||||
typedef(myint, int)
|
||||
var x: PMyInt
|
||||
|
||||
@@ -150,7 +150,7 @@ shadowed by the same argument name even when fully qualified:
|
||||
|
||||
tstLev(levA)
|
||||
# produces: 'levA levA'
|
||||
|
||||
|
||||
But the global symbol can properly be captured by a ``bind`` statement:
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -177,14 +177,14 @@ Per default templates are `hygienic`:idx:\: Local identifiers declared in a
|
||||
template cannot be accessed in the instantiation context:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
|
||||
template newException*(exceptn: typedesc, message: string): expr =
|
||||
var
|
||||
e: ref exceptn # e is implicitly gensym'ed here
|
||||
new(e)
|
||||
e.msg = message
|
||||
e
|
||||
|
||||
|
||||
# so this works:
|
||||
let e = "message"
|
||||
raise newException(EIO, e)
|
||||
@@ -196,7 +196,7 @@ symbols are not exposed but inject'ed are.
|
||||
|
||||
The default for symbols of entity ``type``, ``var``, ``let`` and ``const``
|
||||
is ``gensym`` and for ``proc``, ``iterator``, ``converter``, ``template``,
|
||||
``macro`` is ``inject``. However, if the name of the entity is passed as a
|
||||
``macro`` is ``inject``. However, if the name of the entity is passed as a
|
||||
template parameter, it is an inject'ed symbol:
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -204,7 +204,7 @@ template parameter, it is an inject'ed symbol:
|
||||
block:
|
||||
var f: File # since 'f' is a template param, it's injected implicitly
|
||||
...
|
||||
|
||||
|
||||
withFile(txt, "ttempl3.txt", fmWrite):
|
||||
txt.writeLine("line 1")
|
||||
txt.writeLine("line 2")
|
||||
@@ -215,7 +215,7 @@ no semantics outside of a template definition and cannot be abstracted over:
|
||||
|
||||
.. code-block:: nim
|
||||
{.pragma myInject: inject.}
|
||||
|
||||
|
||||
template t() =
|
||||
var x {.myInject.}: int # does NOT work
|
||||
|
||||
@@ -334,9 +334,9 @@ BindSym
|
||||
-------
|
||||
|
||||
The above ``debug`` macro relies on the fact that ``write``, ``writeLine`` and
|
||||
``stdout`` are declared in the system module and thus visible in the
|
||||
``stdout`` are declared in the system module and thus visible in the
|
||||
instantiating context. There is a way to use bound identifiers
|
||||
(aka `symbols`:idx:) instead of using unbound identifiers. The ``bindSym``
|
||||
(aka `symbols`:idx:) instead of using unbound identifiers. The ``bindSym``
|
||||
builtin can be used for that:
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -418,8 +418,8 @@ powerful programming construct that still suffices. So the "check list" is:
|
||||
Macros as pragmas
|
||||
-----------------
|
||||
|
||||
Whole routines (procs, iterators etc.) can also be passed to a template or
|
||||
a macro via the pragma notation:
|
||||
Whole routines (procs, iterators etc.) can also be passed to a template or
|
||||
a macro via the pragma notation:
|
||||
|
||||
.. code-block:: nim
|
||||
template m(s: stmt) = discard
|
||||
|
||||
@@ -3,32 +3,32 @@ Term rewriting macros
|
||||
|
||||
Term rewriting macros are macros or templates that have not only
|
||||
a *name* but also a *pattern* that is searched for after the semantic checking
|
||||
phase of the compiler: This means they provide an easy way to enhance the
|
||||
phase of the compiler: This means they provide an easy way to enhance the
|
||||
compilation pipeline with user defined optimizations:
|
||||
|
||||
.. code-block:: nim
|
||||
template optMul{`*`(a, 2)}(a: int): int = a+a
|
||||
|
||||
|
||||
let x = 3
|
||||
echo x * 2
|
||||
|
||||
The compiler now rewrites ``x * 2`` as ``x + x``. The code inside the
|
||||
curlies is the pattern to match against. The operators ``*``, ``**``,
|
||||
``|``, ``~`` have a special meaning in patterns if they are written in infix
|
||||
``|``, ``~`` have a special meaning in patterns if they are written in infix
|
||||
notation, so to match verbatim against ``*`` the ordinary function call syntax
|
||||
needs to be used.
|
||||
|
||||
|
||||
Unfortunately optimizations are hard to get right and even the tiny example
|
||||
is **wrong**:
|
||||
is **wrong**:
|
||||
|
||||
.. code-block:: nim
|
||||
template optMul{`*`(a, 2)}(a: int): int = a+a
|
||||
|
||||
|
||||
proc f(): int =
|
||||
echo "side effect!"
|
||||
result = 55
|
||||
|
||||
|
||||
echo f() * 2
|
||||
|
||||
We cannot duplicate 'a' if it denotes an expression that has a side effect!
|
||||
@@ -36,11 +36,11 @@ Fortunately Nim supports side effect analysis:
|
||||
|
||||
.. code-block:: nim
|
||||
template optMul{`*`(a, 2)}(a: int{noSideEffect}): int = a+a
|
||||
|
||||
|
||||
proc f(): int =
|
||||
echo "side effect!"
|
||||
result = 55
|
||||
|
||||
|
||||
echo f() * 2 # not optimized ;-)
|
||||
|
||||
You can make one overload matching with a constraint and one without, and the
|
||||
@@ -53,13 +53,13 @@ blindly:
|
||||
|
||||
.. code-block:: nim
|
||||
template mulIsCommutative{`*`(a, b)}(a, b: int): int = b*a
|
||||
|
||||
|
||||
What optimizers really need to do is a *canonicalization*:
|
||||
|
||||
.. code-block:: nim
|
||||
template canonMul{`*`(a, b)}(a: int{lit}, b: int): int = b*a
|
||||
|
||||
The ``int{lit}`` parameter pattern matches against an expression of
|
||||
The ``int{lit}`` parameter pattern matches against an expression of
|
||||
type ``int``, but only if it's a literal.
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ type ``int``, but only if it's a literal.
|
||||
Parameter constraints
|
||||
---------------------
|
||||
|
||||
The `parameter constraint`:idx: expression can use the operators ``|`` (or),
|
||||
The `parameter constraint`:idx: expression can use the operators ``|`` (or),
|
||||
``&`` (and) and ``~`` (not) and the following predicates:
|
||||
|
||||
=================== =====================================================
|
||||
@@ -75,7 +75,7 @@ Predicate Meaning
|
||||
=================== =====================================================
|
||||
``atom`` The matching node has no children.
|
||||
``lit`` The matching node is a literal like "abc", 12.
|
||||
``sym`` The matching node must be a symbol (a bound
|
||||
``sym`` The matching node must be a symbol (a bound
|
||||
identifier).
|
||||
``ident`` The matching node must be an identifier (an unbound
|
||||
identifier).
|
||||
@@ -101,15 +101,15 @@ Predicate Meaning
|
||||
``enumfield`` A symbol which is a field in an enumeration.
|
||||
``forvar`` A for loop variable.
|
||||
``label`` A label (used in ``block`` statements).
|
||||
``nk*`` The matching AST must have the specified kind.
|
||||
``nk*`` The matching AST must have the specified kind.
|
||||
(Example: ``nkIfStmt`` denotes an ``if`` statement.)
|
||||
``alias`` States that the marked parameter needs to alias
|
||||
``alias`` States that the marked parameter needs to alias
|
||||
with *some* other parameter.
|
||||
``noalias`` States that *every* other parameter must not alias
|
||||
with the marked parameter.
|
||||
=================== =====================================================
|
||||
|
||||
Predicates that share their name with a keyword have to be escaped with
|
||||
Predicates that share their name with a keyword have to be escaped with
|
||||
backticks: `` `const` ``.
|
||||
The ``alias`` and ``noalias`` predicates refer not only to the matching AST,
|
||||
but also to every other bound parameter; syntactically they need to occur after
|
||||
@@ -151,14 +151,14 @@ constant folding, so the following does not work:
|
||||
The reason is that the compiler already transformed the 1 into "1" for
|
||||
the ``echo`` statement. However, a term rewriting macro should not change the
|
||||
semantics anyway. In fact they can be deactivated with the ``--patterns:off``
|
||||
command line option or temporarily with the ``patterns`` pragma.
|
||||
command line option or temporarily with the ``patterns`` pragma.
|
||||
|
||||
|
||||
The ``{}`` operator
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A pattern expression can be bound to a pattern parameter via the ``expr{param}``
|
||||
notation:
|
||||
notation:
|
||||
|
||||
.. code-block:: nim
|
||||
template t{(0|1|2){x}}(x: expr): expr = x+1
|
||||
@@ -176,7 +176,7 @@ The ``~`` operator is the **not** operator in patterns:
|
||||
template t{x = (~x){y} and (~x){z}}(x, y, z: bool): stmt =
|
||||
x = y
|
||||
if x: x = z
|
||||
|
||||
|
||||
var
|
||||
a = false
|
||||
b = true
|
||||
@@ -189,12 +189,12 @@ The ``*`` operator
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``*`` operator can *flatten* a nested binary expression like ``a & b & c``
|
||||
to ``&(a, b, c)``:
|
||||
to ``&(a, b, c)``:
|
||||
|
||||
.. code-block:: nim
|
||||
var
|
||||
calls = 0
|
||||
|
||||
|
||||
proc `&&`(s: varargs[string]): string =
|
||||
result = s[0]
|
||||
for i in 1..len(s)-1: result.add s[i]
|
||||
@@ -211,8 +211,8 @@ to ``&(a, b, c)``:
|
||||
|
||||
The second operator of `*` must be a parameter; it is used to gather all the
|
||||
arguments. The expression ``"my" && (space & "awe" && "some " ) && "concat"``
|
||||
is passed to ``optConc`` in ``a`` as a special list (of kind ``nkArgList``)
|
||||
which is flattened into a call expression; thus the invocation of ``optConc``
|
||||
is passed to ``optConc`` in ``a`` as a special list (of kind ``nkArgList``)
|
||||
which is flattened into a call expression; thus the invocation of ``optConc``
|
||||
produces:
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -245,7 +245,7 @@ all the arguments, but also the matched operators in reverse polish notation:
|
||||
|
||||
var x, y, z: Matrix
|
||||
|
||||
echo x + y * z - x
|
||||
echo x + y * z - x
|
||||
|
||||
This passes the expression ``x + y * z - x`` to the ``optM`` macro as
|
||||
an ``nnkArgList`` node containing::
|
||||
@@ -265,7 +265,7 @@ an ``nnkArgList`` node containing::
|
||||
Parameters
|
||||
----------
|
||||
|
||||
Parameters in a pattern are type checked in the matching process. If a
|
||||
Parameters in a pattern are type checked in the matching process. If a
|
||||
parameter is of the type ``varargs`` it is treated specially and it can match
|
||||
0 or more arguments in the AST to be matched against:
|
||||
|
||||
@@ -275,7 +275,7 @@ parameter is of the type ``varargs`` it is treated specially and it can match
|
||||
((write|writeLine){w})(f, y)
|
||||
}(x, y: varargs[expr], f: File, w: expr) =
|
||||
w(f, x, y)
|
||||
|
||||
|
||||
|
||||
|
||||
Example: Partial evaluation
|
||||
@@ -310,7 +310,7 @@ The following example shows how some form of hoisting can be implemented:
|
||||
|
||||
The ``optPeg`` template optimizes the case of a peg constructor with a string
|
||||
literal, so that the pattern will only be parsed once at program startup and
|
||||
stored in a global ``gl`` which is then re-used. This optimization is called
|
||||
stored in a global ``gl`` which is then re-used. This optimization is called
|
||||
hoisting because it is comparable to classical loop hoisting.
|
||||
|
||||
|
||||
@@ -343,7 +343,7 @@ ordinary routines.
|
||||
Move optimization
|
||||
-----------------
|
||||
|
||||
The ``call`` constraint is particularly useful to implement a move
|
||||
The ``call`` constraint is particularly useful to implement a move
|
||||
optimization for types that have copying semantics:
|
||||
|
||||
.. code-block:: nim
|
||||
|
||||
@@ -301,7 +301,7 @@ matches better than just ``T`` then.
|
||||
proc sayHi(x: var int): string =
|
||||
# matches a var int
|
||||
result = $(x + 10)
|
||||
|
||||
|
||||
proc sayHello(x: int) =
|
||||
var m = x # a mutable version of x
|
||||
echo sayHi(x) # matches the non-var version of sayHi
|
||||
|
||||
@@ -18,6 +18,6 @@ Example:
|
||||
A type section begins with the ``type`` keyword. It contains multiple
|
||||
type definitions. A type definition binds a type to a name. Type definitions
|
||||
can be recursive or even mutually recursive. Mutually recursive types are only
|
||||
possible within a single ``type`` section. Nominal types like ``objects``
|
||||
possible within a single ``type`` section. Nominal types like ``objects``
|
||||
or ``enums`` can only be defined in a ``type`` section.
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ Note that there can be exceptions to these rules. Nim being as flexible as it
|
||||
is, there will be parts of this style guide that don't make sense in certain
|
||||
contexts. Furthermore, just as
|
||||
`Python's style guide<http://legacy.python.org/dev/peps/pep-0008/>`_ changes
|
||||
over time, this style guide will too.
|
||||
over time, this style guide will too.
|
||||
|
||||
These rules will only be enforced for contributions to the Nim
|
||||
codebase and official projects, such as the Nim compiler, the standard library,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
=====================
|
||||
Nimfix User Guide
|
||||
=====================
|
||||
|
||||
:Author: Andreas Rumpf
|
||||
:Version: |nimversion|
|
||||
|
||||
=====================
|
||||
Nimfix User Guide
|
||||
=====================
|
||||
|
||||
:Author: Andreas Rumpf
|
||||
:Version: |nimversion|
|
||||
|
||||
**WARNING**: Nimfix is currently beta-quality.
|
||||
|
||||
|
||||
Nimfix is a tool to help you upgrade from Nimrod (<= version 0.9.6) to
|
||||
Nim (=> version 0.10.0).
|
||||
|
||||
@@ -48,7 +48,7 @@ Options:
|
||||
--wholeProject overwrite every processed file.
|
||||
--checkExtern:on|off style check also extern names
|
||||
--styleCheck:on|off|auto performs style checking for identifiers
|
||||
and suggests an alternative spelling;
|
||||
and suggests an alternative spelling;
|
||||
'auto' corrects the spelling.
|
||||
|
||||
In addition, all command line options of Nim are supported.
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
|
||||
|
||||
Nimgrep is a command line tool for search&replace tasks. It can search for
|
||||
regex or peg patterns and can search whole directories at once. User
|
||||
regex or peg patterns and can search whole directories at once. User
|
||||
confirmation for every single replace operation can be requested.
|
||||
|
||||
Nimgrep has particularly good support for Nim's
|
||||
eccentric *style insensitivity*. Apart from that it is a generic text
|
||||
Nimgrep has particularly good support for Nim's
|
||||
eccentric *style insensitivity*. Apart from that it is a generic text
|
||||
manipulation tool.
|
||||
|
||||
|
||||
@@ -34,10 +34,10 @@ Options:
|
||||
--find, -f find the pattern (default)
|
||||
--replace, -r replace the pattern
|
||||
--peg pattern is a peg
|
||||
--re pattern is a regular expression (default); extended
|
||||
--re pattern is a regular expression (default); extended
|
||||
syntax for the regular expression is always turned on
|
||||
--recursive process directories recursively
|
||||
--confirm confirm each occurrence/replacement; there is a chance
|
||||
--confirm confirm each occurrence/replacement; there is a chance
|
||||
to abort any time without touching the file
|
||||
--stdin read pattern from stdin (to avoid the shell's confusing
|
||||
quoting rules)
|
||||
|
||||
@@ -11,12 +11,12 @@ Introduction
|
||||
============
|
||||
|
||||
niminst is a tool to generate an installer for a Nim program. Currently
|
||||
it can create an installer for Windows
|
||||
it can create an installer for Windows
|
||||
via `Inno Setup <http://www.jrsoftware.org/isinfo.php>`_ as well as
|
||||
installation/deinstallation scripts for UNIX. Later versions will support
|
||||
installation/deinstallation scripts for UNIX. Later versions will support
|
||||
Linux' package management systems.
|
||||
|
||||
niminst works by reading a configuration file that contains all the
|
||||
niminst works by reading a configuration file that contains all the
|
||||
information that it needs to generate an installer for the different operating
|
||||
systems.
|
||||
|
||||
@@ -24,7 +24,7 @@ systems.
|
||||
Configuration file
|
||||
==================
|
||||
|
||||
niminst uses the Nim `parsecfg <parsecfg.html>`_ module to parse the
|
||||
niminst uses the Nim `parsecfg <parsecfg.html>`_ module to parse the
|
||||
configuration file. Here's an example of how the syntax looks like:
|
||||
|
||||
.. include:: doc/mytest.cfg
|
||||
@@ -54,10 +54,10 @@ Key description
|
||||
``OS`` the OSes to generate C code for; for example:
|
||||
``"windows;linux;macosx"``
|
||||
``CPU`` the CPUs to generate C code for; for example:
|
||||
``"i386;amd64;powerpc"``
|
||||
``"i386;amd64;powerpc"``
|
||||
``Authors`` the project's authors
|
||||
``Description`` the project's description
|
||||
``App`` the application's type: "Console" or "GUI". If
|
||||
``App`` the application's type: "Console" or "GUI". If
|
||||
"Console", niminst generates a special batch file
|
||||
for Windows to open up the command line shell.
|
||||
``License`` the filename of the application's license
|
||||
@@ -69,7 +69,7 @@ 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
|
||||
in filenames are supported. If it is a directory name, all files in the
|
||||
directory are used::
|
||||
|
||||
[Config]
|
||||
@@ -87,35 +87,35 @@ will be installed into the OS's configuration directory.
|
||||
Documentation section
|
||||
---------------------
|
||||
|
||||
The ``documentation`` section supports the ``files`` key.
|
||||
Listed files will be installed into the OS's native documentation directory
|
||||
The ``documentation`` section supports the ``files`` key.
|
||||
Listed files will be installed into the OS's native documentation directory
|
||||
(which might be ``$appdir/doc``).
|
||||
|
||||
There is a ``start`` key which determines whether the Windows installer
|
||||
There is a ``start`` key which determines whether the Windows installer
|
||||
generates a link to e.g. the ``index.html`` of your documentation.
|
||||
|
||||
|
||||
Other section
|
||||
-------------
|
||||
|
||||
The ``other`` section currently only supports the ``files`` key.
|
||||
Listed files will be installed into the application installation directory
|
||||
The ``other`` section currently only supports the ``files`` key.
|
||||
Listed files will be installed into the application installation directory
|
||||
(``$appdir``).
|
||||
|
||||
|
||||
Lib section
|
||||
-----------
|
||||
|
||||
The ``lib`` section currently only supports the ``files`` key.
|
||||
Listed files will be installed into the OS's native library directory
|
||||
The ``lib`` section currently only supports the ``files`` key.
|
||||
Listed files will be installed into the OS's native library directory
|
||||
(which might be ``$appdir/lib``).
|
||||
|
||||
|
||||
Windows section
|
||||
---------------
|
||||
|
||||
The ``windows`` section supports the ``files`` key for Windows specific files.
|
||||
Listed files will be installed into the application installation directory
|
||||
The ``windows`` section supports the ``files`` key for Windows specific files.
|
||||
Listed files will be installed into the application installation directory
|
||||
(``$appdir``).
|
||||
|
||||
Other possible options are:
|
||||
@@ -133,8 +133,8 @@ Key description
|
||||
UnixBin section
|
||||
---------------
|
||||
|
||||
The ``UnixBin`` section currently only supports the ``files`` key.
|
||||
Listed files will be installed into the OS's native bin directory
|
||||
The ``UnixBin`` section currently only supports the ``files`` key.
|
||||
Listed files will be installed into the OS's native bin directory
|
||||
(e.g. ``/usr/local/bin``). The exact location depends on the
|
||||
installation path the user specifies when running the ``install.sh`` script.
|
||||
|
||||
@@ -150,7 +150,7 @@ Key description
|
||||
``InstallScript`` boolean flag whether an installation shell script
|
||||
should be generated. Example: ``InstallScript: "Yes"``
|
||||
``UninstallScript`` boolean flag whether a deinstallation shell script
|
||||
should be generated.
|
||||
should be generated.
|
||||
Example: ``UninstallScript: "Yes"``
|
||||
==================== =======================================================
|
||||
|
||||
@@ -163,7 +163,7 @@ Possible options are:
|
||||
==================== =======================================================
|
||||
Key description
|
||||
==================== =======================================================
|
||||
``path`` Path to Inno Setup.
|
||||
``path`` Path to Inno Setup.
|
||||
Example: ``path = r"c:\inno setup 5\iscc.exe"``
|
||||
``flags`` Flags to pass to Inno Setup.
|
||||
Example: ``flags = "/Q"``
|
||||
@@ -178,7 +178,7 @@ Possible options are:
|
||||
==================== =======================================================
|
||||
Key description
|
||||
==================== =======================================================
|
||||
``path`` Path to the C compiler.
|
||||
``path`` Path to the C compiler.
|
||||
``flags`` Flags to pass to the C Compiler.
|
||||
Example: ``flags = "-w"``
|
||||
==================== =======================================================
|
||||
|
||||
@@ -14,7 +14,7 @@ notation meaning
|
||||
order, to the text ahead, until one of them succeeds and
|
||||
possibly consumes some text. Indicate success if one of
|
||||
expressions succeeded. Otherwise do not consume any text
|
||||
and indicate failure.
|
||||
and indicate failure.
|
||||
``A ... Z`` Sequence: Apply expressions `A`, ..., `Z`, in this order,
|
||||
to consume consecutive portions of the text ahead, as long
|
||||
as they succeed. Indicate success if all succeeded.
|
||||
@@ -27,11 +27,11 @@ notation meaning
|
||||
``{E}`` Capture: Apply expression `E` and store the substring
|
||||
that matched `E` into a *capture* that can be accessed
|
||||
after the matching process.
|
||||
``$i`` Back reference to the ``i``th capture. ``i`` counts from 1.
|
||||
``$`` Anchor: Matches at the end of the input. No character
|
||||
is consumed. Same as ``!.``.
|
||||
``^`` Anchor: Matches at the start of the input. No character
|
||||
is consumed.
|
||||
``$i`` Back reference to the ``i``th capture. ``i`` counts from 1.
|
||||
``$`` Anchor: Matches at the end of the input. No character
|
||||
is consumed. Same as ``!.``.
|
||||
``^`` Anchor: Matches at the start of the input. No character
|
||||
is consumed.
|
||||
``&E`` And predicate: Indicate success if expression `E` matches
|
||||
the text ahead; otherwise indicate failure. Do not consume
|
||||
any text.
|
||||
@@ -41,15 +41,15 @@ notation meaning
|
||||
``E+`` One or more: Apply expression `E` repeatedly to match
|
||||
the text ahead, as long as it succeeds. Consume the matched
|
||||
text (if any) and indicate success if there was at least
|
||||
one match. Otherwise indicate failure.
|
||||
one match. Otherwise indicate failure.
|
||||
``E*`` Zero or more: Apply expression `E` repeatedly to match
|
||||
the text ahead, as long as it succeeds. Consume the matched
|
||||
text (if any). Always indicate success.
|
||||
text (if any). Always indicate success.
|
||||
``E?`` Zero or one: If expression `E` matches the text ahead,
|
||||
consume it. Always indicate success.
|
||||
consume it. Always indicate success.
|
||||
``[s]`` Character class: If the character ahead appears in the
|
||||
string `s`, consume it and indicate success. Otherwise
|
||||
indicate failure.
|
||||
indicate failure.
|
||||
``[a-b]`` Character range: If the character ahead is one from the
|
||||
range `a` through `b`, consume it and indicate success.
|
||||
Otherwise indicate failure.
|
||||
@@ -70,7 +70,7 @@ notation meaning
|
||||
failure.
|
||||
``@E`` Search: Shorthand for ``(!E .)* E``. (Search loop for the
|
||||
pattern `E`.)
|
||||
``{@} E`` Captured Search: Shorthand for ``{(!E .)*} E``. (Search
|
||||
``{@} E`` Captured Search: Shorthand for ``{(!E .)*} E``. (Search
|
||||
loop for the pattern `E`.) Everything until and exluding
|
||||
`E` is captured.
|
||||
``@@ E`` Same as ``{@} E``.
|
||||
@@ -79,7 +79,7 @@ notation meaning
|
||||
matching engine.**
|
||||
``\identifier`` Built-in macro for a longer expression.
|
||||
``\ddd`` Character with decimal code *ddd*.
|
||||
``\"``, etc Literal ``"``, etc.
|
||||
``\"``, etc Literal ``"``, etc.
|
||||
=============== ============================================================
|
||||
|
||||
|
||||
@@ -101,9 +101,9 @@ macro meaning
|
||||
``\n`` any newline combination: ``\10 / \13\10 / \13``
|
||||
``\i`` ignore case for matching; use this at the start of the PEG
|
||||
``\y`` ignore style for matching; use this at the start of the PEG
|
||||
``\skip`` pat skip pattern *pat* before trying to match other tokens;
|
||||
``\skip`` pat skip pattern *pat* before trying to match other tokens;
|
||||
this is useful for whitespace skipping, for example:
|
||||
``\skip(\s*) {\ident} ':' {\ident}`` matches key value
|
||||
``\skip(\s*) {\ident} ':' {\ident}`` matches key value
|
||||
pairs ignoring whitespace around the ``':'``.
|
||||
``\ident`` a standard ASCII identifier: ``[a-zA-Z_][a-zA-Z_0-9]*``
|
||||
``\letter`` any Unicode letter
|
||||
@@ -133,42 +133,42 @@ 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.
|
||||
|
||||
|
||||
grammar <- rule* / expr
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
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 identNoArrow /
|
||||
ig charset /
|
||||
ig stringlit /
|
||||
ig builtin /
|
||||
ig '.' /
|
||||
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``
|
||||
|
||||
|
||||
seqExpr <- primary+
|
||||
expr <- seqExpr (ig "/" expr)*
|
||||
|
||||
|
||||
**Note**: As a special syntactic extension if the whole PEG is only a single
|
||||
expression, identifiers are not interpreted as non-terminals, but are
|
||||
**Note**: As a special syntactic extension if the whole PEG is only a single
|
||||
expression, identifiers are not interpreted as non-terminals, but are
|
||||
interpreted as verbatim string:
|
||||
|
||||
.. code-block:: nim
|
||||
@@ -185,7 +185,7 @@ Check if `s` matches Nim's "while" keyword:
|
||||
.. code-block:: nim
|
||||
s =~ peg" y'while'"
|
||||
|
||||
Exchange (key, val)-pairs:
|
||||
Exchange (key, val)-pairs:
|
||||
|
||||
.. code-block:: nim
|
||||
"key: val; key2: val2".replacef(peg"{\ident} \s* ':' \s* {\ident}", "$2: $1")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
============================
|
||||
Nim's documenation system
|
||||
============================
|
||||
|
||||
This folder contains Nim's documentation. The documentation
|
||||
is written in a format called *reStructuredText*, a markup language that reads
|
||||
like ASCII and can be converted to HTML automatically!
|
||||
============================
|
||||
Nim's documenation system
|
||||
============================
|
||||
|
||||
This folder contains Nim's documentation. The documentation
|
||||
is written in a format called *reStructuredText*, a markup language that reads
|
||||
like ASCII and can be converted to HTML automatically!
|
||||
|
||||
@@ -175,17 +175,17 @@ for themselves. For example:
|
||||
example meaning
|
||||
============== ============================================================
|
||||
``\040`` is another way of writing a space
|
||||
``\40`` is the same, provided there are fewer than 40 previous
|
||||
``\40`` is the same, provided there are fewer than 40 previous
|
||||
capturing subpatterns
|
||||
``\7`` is always a back reference
|
||||
``\11`` might be a back reference, or another way of writing a tab
|
||||
``\011`` is always a tab
|
||||
``\0113`` is a tab followed by the character "3"
|
||||
``\113`` might be a back reference, otherwise the character with
|
||||
``\113`` might be a back reference, otherwise the character with
|
||||
octal code 113
|
||||
``\377`` might be a back reference, otherwise the byte consisting
|
||||
``\377`` might be a back reference, otherwise the byte consisting
|
||||
entirely of 1 bits
|
||||
``\81`` is either a back reference, or a binary zero followed by
|
||||
``\81`` is either a back reference, or a binary zero followed by
|
||||
the two characters "8" and "1"
|
||||
============== ============================================================
|
||||
|
||||
@@ -240,7 +240,7 @@ even when Unicode character property support is available.
|
||||
|
||||
Simple assertions
|
||||
-----------------
|
||||
The fourth use of backslash is for certain `simple assertions`:idx:. An
|
||||
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
|
||||
|
||||
@@ -4,7 +4,7 @@ basetype can only be an ordinal type of a certain size, namely:
|
||||
* ``uint8``/``byte``-``uint16``
|
||||
* ``char``
|
||||
* ``enum``
|
||||
or equivalent. The reason is that sets are implemented as high
|
||||
or equivalent. The reason is that sets are implemented as high
|
||||
performance bit vectors. Attempting to declare a set with a larger type will
|
||||
result in an error:
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Parallel & Spawn
|
||||
==========================================================
|
||||
|
||||
Nim has two flavors of parallelism:
|
||||
Nim has two flavors of parallelism:
|
||||
1) `Structured`:idx parallelism via the ``parallel`` statement.
|
||||
2) `Unstructured`:idx: parallelism via the standalone ``spawn`` statement.
|
||||
|
||||
@@ -30,7 +30,7 @@ variables at the same time:
|
||||
|
||||
.. code-block:: nim
|
||||
import threadpool, ...
|
||||
|
||||
|
||||
# wait until 2 out of 3 servers received the update:
|
||||
proc main =
|
||||
var responses = newSeq[FlowVarBase](3)
|
||||
@@ -89,7 +89,7 @@ restrictions / changes:
|
||||
the ``parallel`` section. This is called the *immutability check*. Currently
|
||||
it is not specified what exactly "complex location" means. We need to make
|
||||
this an optimization!
|
||||
* Every array access has to be provably within bounds. This is called
|
||||
* Every array access has to be provably within bounds. This is called
|
||||
the *bounds check*.
|
||||
* Slices are optimized so that no copy is performed. This optimization is not
|
||||
yet performed for ordinary slices outside of a ``parallel`` section. Slices
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
Substitution Expressions (subex)
|
||||
================================
|
||||
|
||||
A *subex* (*Substitution Expression*) represents an advanted string
|
||||
A *subex* (*Substitution Expression*) represents an advanted string
|
||||
substitution. In contrast to a `regex`:idx: which deals with string analysis, a
|
||||
*subex* deals with string synthesis.
|
||||
|
||||
Thanks to its conditional construct ``$[0|1|2|else]`` it supports
|
||||
Thanks to its conditional construct ``$[0|1|2|else]`` it supports
|
||||
`internationalization`:idx: of format string literals quite well.
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ Notation meaning
|
||||
``$[zero|one|def]1`` use ``X = parseInt(arg[1])`` to determine which
|
||||
branch to use. If ``X == 0`` the 'zero' branch is
|
||||
selected, if ``X == 1`` the 'one' branch is
|
||||
selected, etc. Otherwise the 'def' branch is
|
||||
selected, etc. Otherwise the 'def' branch is
|
||||
selected. ``$x`` is interpreted in branches too.
|
||||
If a branch needs to contain ``|``, ``]`` put
|
||||
them in single quotes. To produce a verbatim single
|
||||
@@ -50,12 +50,12 @@ Examples
|
||||
.. code-block:: nim
|
||||
|
||||
subex"$1($', '{2..})" % ["f", "a", "b", "c"] == "f(a, b, c)"
|
||||
|
||||
|
||||
subex"$1 $[files|file|files]{1} copied" % ["1"] == "1 file copied"
|
||||
|
||||
|
||||
subex"$['''|'|''''|']']#" % "0" == "'|"
|
||||
|
||||
|
||||
subex("type\n TEnum = enum\n $', '40c'\n '{..}") % [
|
||||
"fieldNameA", "fieldNameB", "fieldNameC", "fieldNameD"]
|
||||
|
||||
|
||||
|
||||
|
||||
10
doc/tut1.txt
10
doc/tut1.txt
@@ -1280,19 +1280,19 @@ with a compatible base type can be passed to an openarray parameter, the index
|
||||
type does not matter.
|
||||
|
||||
.. code-block:: nim
|
||||
var
|
||||
var
|
||||
fruits: seq[string] # reference to a sequence of strings that is initialized with 'nil'
|
||||
capitals: array[3, string] # array of strings with a fixed size
|
||||
|
||||
|
||||
fruits = @[] # creates an empty sequence on the heap that will be referenced by 'fruits'
|
||||
|
||||
|
||||
capitals = ["New York", "London", "Berlin"] # array 'capitals' allows only assignment of three elements
|
||||
fruits.add("Banana") # sequence 'fruits' is dynamically expandable during runtime
|
||||
fruits.add("Mango")
|
||||
|
||||
|
||||
proc openArraySize(oa: openArray[string]): int =
|
||||
oa.len
|
||||
|
||||
|
||||
assert openArraySize(fruits) == 2 # procedure accepts a sequence as parameter
|
||||
assert openArraySize(capitals) == 3 # but also an array type
|
||||
|
||||
|
||||
Reference in New Issue
Block a user