bind table
This commit is contained in:
parent
d5acb88ccc
commit
ac421c37ba
18 changed files with 957 additions and 384 deletions
|
|
@ -20,7 +20,7 @@ contains:
|
||||||
|
|
||||||
PNimrodNode = ref TNimrodNode
|
PNimrodNode = ref TNimrodNode
|
||||||
TNimrodNode {.final.} = object
|
TNimrodNode {.final.} = object
|
||||||
case kind ## the node's kind
|
case kind: TNimrodNodeKind ## the node's kind
|
||||||
of nnkNone, nnkEmpty, nnkNilLit:
|
of nnkNone, nnkEmpty, nnkNilLit:
|
||||||
nil ## node contains no additional fields
|
nil ## node contains no additional fields
|
||||||
of nnkCharLit..nnkInt64Lit:
|
of nnkCharLit..nnkInt64Lit:
|
||||||
|
|
@ -43,6 +43,11 @@ To specify the AST for the different Nimrod constructs, the notation
|
||||||
``nodekind(son1, son2, ...)`` or ``nodekind(value)`` or
|
``nodekind(son1, son2, ...)`` or ``nodekind(value)`` or
|
||||||
``nodekind(field=value)`` is used.
|
``nodekind(field=value)`` is used.
|
||||||
|
|
||||||
|
Some child may be missing. Then it is ``nil``. A nil child is equivalent to
|
||||||
|
a node of kind ``nnkEmpty``. This is more or less a (useful) artifact from
|
||||||
|
the implementation. (In the compiler's implementation ``nil`` is of course
|
||||||
|
not the same as ``nnkEmpty``!)
|
||||||
|
|
||||||
|
|
||||||
Leaf nodes/Atoms
|
Leaf nodes/Atoms
|
||||||
================
|
================
|
||||||
|
|
@ -72,7 +77,8 @@ Nimrod expression corresponding AST
|
||||||
Identifiers are ``nnkIdent`` nodes. After the name lookup pass these nodes
|
Identifiers are ``nnkIdent`` nodes. After the name lookup pass these nodes
|
||||||
get transferred into ``nnkSym`` nodes. However, a macro receives an AST that
|
get transferred into ``nnkSym`` nodes. However, a macro receives an AST that
|
||||||
has not been checked for semantics and thus the identifiers have not been
|
has not been checked for semantics and thus the identifiers have not been
|
||||||
looked up. Thus macros deal with ``nnkIdent`` nodes.
|
looked up. Macros should deal with ``nnkIdent`` nodes and do not need to deal
|
||||||
|
with ``nnkSym`` nodes.
|
||||||
|
|
||||||
|
|
||||||
Calls/expressions
|
Calls/expressions
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ Parsers and Filters
|
||||||
|
|
||||||
.. contents::
|
.. contents::
|
||||||
|
|
||||||
The Nimrod compiler contains multiple parsers. (The standard is
|
The Nimrod compiler contains multiple parsers. The standard is
|
||||||
indentation-based.) Two others are available: The `braces`:idx: parser and the
|
indentation-based. Two others are available: The `braces`:idx: parser and the
|
||||||
`endX`:idx: parser. Both parsers use the same lexer as the standard parser.
|
`endX`:idx: parser. Both parsers use the same lexer as the standard parser.
|
||||||
|
|
||||||
To use a different parser for a source file the *shebang* notation is used:
|
To use a different parser for a source file the *shebang* notation is used:
|
||||||
|
|
|
||||||
|
|
@ -951,7 +951,7 @@ of the following conditions hold:
|
||||||
3) The procedure has a calling convention that differs from ``nimcall``.
|
3) The procedure has a calling convention that differs from ``nimcall``.
|
||||||
4) The procedure is anonymous.
|
4) The procedure is anonymous.
|
||||||
|
|
||||||
These rules should prevent the case that extending a non-``procvar``
|
The rules' purpose is to prevent the case that extending a non-``procvar``
|
||||||
procedure with default parameters breaks client code.
|
procedure with default parameters breaks client code.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1800,7 +1800,7 @@ return values. This can be done in a cleaner way by returning a tuple:
|
||||||
assert t.res == 1
|
assert t.res == 1
|
||||||
assert t.remainder = 3
|
assert t.remainder = 3
|
||||||
|
|
||||||
Even more elegant is to use `tuple unpacking`:idx: to access the tuple's fields:
|
One can use `tuple unpacking`:idx: to access the tuple's fields:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
var (x, y) = divmod(8, 5) # tuple unpacking
|
var (x, y) = divmod(8, 5) # tuple unpacking
|
||||||
|
|
@ -1872,7 +1872,7 @@ dispatching:
|
||||||
|
|
||||||
Invokation of a multi-method cannot be ambiguous: Collide 2 is prefered over
|
Invokation of a multi-method cannot be ambiguous: Collide 2 is prefered over
|
||||||
collide 1 because the resolution works from left to right.
|
collide 1 because the resolution works from left to right.
|
||||||
Thus ``TUnit, TThing`` is prefered over ``TThing, TUnit``.
|
In the example ``TUnit, TThing`` is prefered over ``TThing, TUnit``.
|
||||||
|
|
||||||
**Perfomance note**: Nimrod does not produce a virtual method table, but
|
**Perfomance note**: Nimrod does not produce a virtual method table, but
|
||||||
generates dispatch trees. This avoids the expensive indirect branch for method
|
generates dispatch trees. This avoids the expensive indirect branch for method
|
||||||
|
|
@ -2112,6 +2112,44 @@ special ``:`` syntax:
|
||||||
In the example the two ``writeln`` statements are bound to the ``actions``
|
In the example the two ``writeln`` statements are bound to the ``actions``
|
||||||
parameter.
|
parameter.
|
||||||
|
|
||||||
|
Symbol binding within templates happens after template instantation:
|
||||||
|
|
||||||
|
.. code-block:: nimrod
|
||||||
|
# Module A
|
||||||
|
var
|
||||||
|
lastId = 0
|
||||||
|
|
||||||
|
template genId*: expr =
|
||||||
|
inc(lastId)
|
||||||
|
lastId
|
||||||
|
|
||||||
|
.. code-block:: nimrod
|
||||||
|
# Module B
|
||||||
|
import A
|
||||||
|
|
||||||
|
echo genId() # Error: undeclared identifier: 'lastId'
|
||||||
|
|
||||||
|
Exporting a template is a often a leaky abstraction. However, to compensate for
|
||||||
|
this case, the ``bind`` operator can be used: All identifiers
|
||||||
|
within a ``bind`` context are bound early (i.e. when the template is parsed).
|
||||||
|
The affected identifiers are then always bound early even if the other
|
||||||
|
occurences are in no ``bind`` context:
|
||||||
|
|
||||||
|
.. code-block:: nimrod
|
||||||
|
# Module A
|
||||||
|
var
|
||||||
|
lastId = 0
|
||||||
|
|
||||||
|
template genId*: expr =
|
||||||
|
inc(bind lastId)
|
||||||
|
lastId
|
||||||
|
|
||||||
|
.. code-block:: nimrod
|
||||||
|
# Module B
|
||||||
|
import A
|
||||||
|
|
||||||
|
echo genId() # Works
|
||||||
|
|
||||||
|
|
||||||
**Style note**: For code readability, it is the best idea to use the least
|
**Style note**: For code readability, it is the best idea to use the least
|
||||||
powerful programming construct that still suffices. So the "check list" is:
|
powerful programming construct that still suffices. So the "check list" is:
|
||||||
|
|
@ -2356,7 +2394,7 @@ verify this.
|
||||||
|
|
||||||
procvar pragma
|
procvar pragma
|
||||||
--------------
|
--------------
|
||||||
The `procvar`:idx: pragma is used to mark a proc that it can be passed to a
|
The `procvar`:idx: pragma is used to mark a proc so that it can be passed to a
|
||||||
procedural variable.
|
procedural variable.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,21 @@ In general, importing a dynamic library does not require any special linker
|
||||||
options or linking with import libraries. This also implies that no *devel*
|
options or linking with import libraries. This also implies that no *devel*
|
||||||
packages need to be installed.
|
packages need to be installed.
|
||||||
|
|
||||||
|
The ``dynlib`` import mechanism supports a versioning scheme:
|
||||||
|
|
||||||
|
.. code-block:: nimrod
|
||||||
|
proc Tcl_Eval(interp: pTcl_Interp, script: cstring): int {.cdecl,
|
||||||
|
importc, dynlib: "libtcl(8.5|8.4|8.3).so.(1|0)".}
|
||||||
|
|
||||||
|
At runtime the dynamic library is searched for (in this order)::
|
||||||
|
|
||||||
|
libtcl8.5.so.1
|
||||||
|
libtcl8.4.so.1
|
||||||
|
libtcl8.3.so.1
|
||||||
|
libtcl8.5.so.0
|
||||||
|
libtcl8.4.so.0
|
||||||
|
libtcl8.3.so.0
|
||||||
|
|
||||||
|
|
||||||
No_decl Pragma
|
No_decl Pragma
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
|
|
@ -231,7 +246,7 @@ compiler to activate (or deactivate) dead code elimination for the module the
|
||||||
pragma appers in.
|
pragma appers in.
|
||||||
|
|
||||||
The ``--dead_code_elim:on`` command line switch has the same effect as marking
|
The ``--dead_code_elim:on`` command line switch has the same effect as marking
|
||||||
any module with ``{.dead_code_elim:on}``. However, for some modules such as
|
every module with ``{.dead_code_elim:on}``. However, for some modules such as
|
||||||
the GTK wrapper it makes sense to *always* turn on dead code elimination -
|
the GTK wrapper it makes sense to *always* turn on dead code elimination -
|
||||||
no matter if it is globally active or not.
|
no matter if it is globally active or not.
|
||||||
|
|
||||||
|
|
@ -244,7 +259,7 @@ Example:
|
||||||
Disabling certain messages
|
Disabling certain messages
|
||||||
--------------------------
|
--------------------------
|
||||||
Nimrod generates some warnings and hints ("line too long") that may annoy the
|
Nimrod generates some warnings and hints ("line too long") that may annoy the
|
||||||
user. Thus a mechanism for disabling certain messages is provided: Each hint
|
user. A mechanism for disabling certain messages is provided: Each hint
|
||||||
and warning message contains a symbol in brackets. This is the message's
|
and warning message contains a symbol in brackets. This is the message's
|
||||||
identifier that can be used to enable or disable it:
|
identifier that can be used to enable or disable it:
|
||||||
|
|
||||||
|
|
@ -300,9 +315,10 @@ However it is not efficient to do:
|
||||||
.. code-block:: Nimrod
|
.. code-block:: Nimrod
|
||||||
var s = varA # assignment has to copy the whole string into a new buffer!
|
var s = varA # assignment has to copy the whole string into a new buffer!
|
||||||
|
|
||||||
String case statements are optimized too. A hashing scheme is used for them
|
..
|
||||||
if several different string constants are used. This is likely to be more
|
String case statements are optimized too. A hashing scheme is used for them
|
||||||
efficient than any hand-coded scheme.
|
if several different string constants are used. This is likely to be more
|
||||||
|
efficient than any hand-coded scheme.
|
||||||
|
|
||||||
|
|
||||||
..
|
..
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,8 @@ notation meaning
|
||||||
``_`` Any Unicode character: If there is an UTF-8 character
|
``_`` Any Unicode character: If there is an UTF-8 character
|
||||||
ahead, consume it and indicate success. Otherwise indicate
|
ahead, consume it and indicate success. Otherwise indicate
|
||||||
failure.
|
failure.
|
||||||
|
``@E`` Search: Shorthand for ``(!E .)* E``. (Search loop for the
|
||||||
|
pattern `E`.)
|
||||||
``A <- E`` Rule: Bind the expression `E` to the *nonterminal symbol*
|
``A <- E`` Rule: Bind the expression `E` to the *nonterminal symbol*
|
||||||
`A`. **Left recursive rules are not possible and crash the
|
`A`. **Left recursive rules are not possible and crash the
|
||||||
matching engine.**
|
matching engine.**
|
||||||
|
|
@ -118,14 +120,15 @@ The PEG parser implements this grammar (written in PEG syntax)::
|
||||||
"'" ("\\" . / [^'])* "'")
|
"'" ("\\" . / [^'])* "'")
|
||||||
builtin <- "\\" identifier / [^\13\10]
|
builtin <- "\\" identifier / [^\13\10]
|
||||||
|
|
||||||
comment <- '#' !\n* \n
|
comment <- '#' @ \n
|
||||||
ig <- (\s / comment)* # things to ignore
|
ig <- (\s / comment)* # things to ignore
|
||||||
|
|
||||||
rule <- identifier \s* "<-" expr ig
|
rule <- identifier \s* "<-" expr ig
|
||||||
identNoArrow <- identifier !(\s* "<-")
|
identNoArrow <- identifier !(\s* "<-")
|
||||||
primary <- (ig '&' / ig '!')* ((ig identNoArrow / ig charset / ig stringlit
|
primary <- (ig '&' / ig '!' / ig '@')*
|
||||||
/ ig builtin / ig '.' / ig '_'
|
((ig identNoArrow / ig charset / ig stringlit
|
||||||
/ (ig "(" expr ig ")"))
|
/ ig builtin / ig '.' / ig '_'
|
||||||
|
/ (ig "(" expr ig ")"))
|
||||||
(ig '?' / ig '*' / ig '+')*)
|
(ig '?' / ig '*' / ig '+')*)
|
||||||
|
|
||||||
# Concatenation has higher priority than choice:
|
# Concatenation has higher priority than choice:
|
||||||
|
|
@ -153,16 +156,16 @@ Determine the ``#include``'ed files of a C file:
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
for line in lines("myfile.c"):
|
for line in lines("myfile.c"):
|
||||||
if line =~ peg"""s <- ws '#include' ws '"' {[^"]+} '"' ws
|
if line =~ peg"""s <- ws '#include' ws '"' {[^"]+} '"' ws
|
||||||
comment <- '/*' (!'*/' . )* '*/' / '//' .*
|
comment <- '/*' @ '*/' / '//' .*
|
||||||
ws <- (comment / \s+)* """:
|
ws <- (comment / \s+)* """:
|
||||||
echo matches[0]
|
echo matches[0]
|
||||||
|
|
||||||
PEG vs regular expression
|
PEG vs regular expression
|
||||||
-------------------------
|
-------------------------
|
||||||
As a regular expression ``\[.*\]`` maches longest possible text between ``'['``
|
As a regular expression ``\[.*\]`` matches the longest possible text between
|
||||||
and ``']'``. As a PEG it never matches anything, because a PEG is
|
``'['`` and ``']'``. As a PEG it never matches anything, because a PEG is
|
||||||
deterministic: ``.*`` consumes the rest of the input, so ``\]`` never matches.
|
deterministic: ``.*`` consumes the rest of the input, so ``\]`` never matches.
|
||||||
As a PEG this needs to be written as: ``\[ ( !\] . )* \]``
|
As a PEG this needs to be written as: ``\[ ( !\] . )* \]`` (or ``\[ @ \]``).
|
||||||
|
|
||||||
Note that the regular expression does not behave as intended either:
|
Note that the regular expression does not behave as intended either:
|
||||||
``*`` should not be greedy, so ``\[.*?\]`` should be used.
|
``*`` should not be greedy, so ``\[.*?\]`` should be used.
|
||||||
|
|
|
||||||
239
doc/theindex.txt
239
doc/theindex.txt
|
|
@ -7,7 +7,7 @@ Index
|
||||||
|
|
||||||
|
|
||||||
`!`:idx:
|
`!`:idx:
|
||||||
* `pegs.html#114 <pegs.html#114>`_
|
* `pegs.html#115 <pegs.html#115>`_
|
||||||
* `macros.html#114 <macros.html#114>`_
|
* `macros.html#114 <macros.html#114>`_
|
||||||
|
|
||||||
`!=`:idx:
|
`!=`:idx:
|
||||||
|
|
@ -24,7 +24,7 @@ Index
|
||||||
* `system.html#426 <system.html#426>`_
|
* `system.html#426 <system.html#426>`_
|
||||||
* `times.html#109 <times.html#109>`_
|
* `times.html#109 <times.html#109>`_
|
||||||
* `times.html#110 <times.html#110>`_
|
* `times.html#110 <times.html#110>`_
|
||||||
* `pegs.html#148 <pegs.html#148>`_
|
* `pegs.html#133 <pegs.html#133>`_
|
||||||
* `macros.html#115 <macros.html#115>`_
|
* `macros.html#115 <macros.html#115>`_
|
||||||
|
|
||||||
`%`:idx:
|
`%`:idx:
|
||||||
|
|
@ -47,7 +47,7 @@ Index
|
||||||
* `system.html#462 <system.html#462>`_
|
* `system.html#462 <system.html#462>`_
|
||||||
* `system.html#463 <system.html#463>`_
|
* `system.html#463 <system.html#463>`_
|
||||||
* `system.html#464 <system.html#464>`_
|
* `system.html#464 <system.html#464>`_
|
||||||
* `pegs.html#113 <pegs.html#113>`_
|
* `pegs.html#114 <pegs.html#114>`_
|
||||||
|
|
||||||
`*`:idx:
|
`*`:idx:
|
||||||
* `system.html#212 <system.html#212>`_
|
* `system.html#212 <system.html#212>`_
|
||||||
|
|
@ -82,7 +82,7 @@ Index
|
||||||
* `system.html#309 <system.html#309>`_
|
* `system.html#309 <system.html#309>`_
|
||||||
* `system.html#320 <system.html#320>`_
|
* `system.html#320 <system.html#320>`_
|
||||||
* `complex.html#103 <complex.html#103>`_
|
* `complex.html#103 <complex.html#103>`_
|
||||||
* `pegs.html#112 <pegs.html#112>`_
|
* `pegs.html#113 <pegs.html#113>`_
|
||||||
|
|
||||||
`+%`:idx:
|
`+%`:idx:
|
||||||
* `system.html#272 <system.html#272>`_
|
* `system.html#272 <system.html#272>`_
|
||||||
|
|
@ -152,9 +152,6 @@ Index
|
||||||
* `system.html#346 <system.html#346>`_
|
* `system.html#346 <system.html#346>`_
|
||||||
* `times.html#114 <times.html#114>`_
|
* `times.html#114 <times.html#114>`_
|
||||||
|
|
||||||
`<%`:idx:
|
|
||||||
`unicode.html#104 <unicode.html#104>`_
|
|
||||||
|
|
||||||
`<%`:idx:
|
`<%`:idx:
|
||||||
* `system.html#302 <system.html#302>`_
|
* `system.html#302 <system.html#302>`_
|
||||||
* `system.html#303 <system.html#303>`_
|
* `system.html#303 <system.html#303>`_
|
||||||
|
|
@ -162,6 +159,9 @@ Index
|
||||||
* `system.html#305 <system.html#305>`_
|
* `system.html#305 <system.html#305>`_
|
||||||
* `system.html#306 <system.html#306>`_
|
* `system.html#306 <system.html#306>`_
|
||||||
|
|
||||||
|
`<%`:idx:
|
||||||
|
`unicode.html#104 <unicode.html#104>`_
|
||||||
|
|
||||||
`<=`:idx:
|
`<=`:idx:
|
||||||
* `system.html#257 <system.html#257>`_
|
* `system.html#257 <system.html#257>`_
|
||||||
* `system.html#258 <system.html#258>`_
|
* `system.html#258 <system.html#258>`_
|
||||||
|
|
@ -180,6 +180,9 @@ Index
|
||||||
`<=`:idx:
|
`<=`:idx:
|
||||||
`times.html#115 <times.html#115>`_
|
`times.html#115 <times.html#115>`_
|
||||||
|
|
||||||
|
`<=%`:idx:
|
||||||
|
`unicode.html#103 <unicode.html#103>`_
|
||||||
|
|
||||||
`<=%`:idx:
|
`<=%`:idx:
|
||||||
* `system.html#297 <system.html#297>`_
|
* `system.html#297 <system.html#297>`_
|
||||||
* `system.html#298 <system.html#298>`_
|
* `system.html#298 <system.html#298>`_
|
||||||
|
|
@ -187,9 +190,6 @@ Index
|
||||||
* `system.html#300 <system.html#300>`_
|
* `system.html#300 <system.html#300>`_
|
||||||
* `system.html#301 <system.html#301>`_
|
* `system.html#301 <system.html#301>`_
|
||||||
|
|
||||||
`<=%`:idx:
|
|
||||||
`unicode.html#103 <unicode.html#103>`_
|
|
||||||
|
|
||||||
`==`:idx:
|
`==`:idx:
|
||||||
* `md5.html#107 <md5.html#107>`_
|
* `md5.html#107 <md5.html#107>`_
|
||||||
* `system.html#252 <system.html#252>`_
|
* `system.html#252 <system.html#252>`_
|
||||||
|
|
@ -211,12 +211,13 @@ Index
|
||||||
* `complex.html#102 <complex.html#102>`_
|
* `complex.html#102 <complex.html#102>`_
|
||||||
* `unicode.html#105 <unicode.html#105>`_
|
* `unicode.html#105 <unicode.html#105>`_
|
||||||
* `macros.html#116 <macros.html#116>`_
|
* `macros.html#116 <macros.html#116>`_
|
||||||
|
* `macros.html#117 <macros.html#117>`_
|
||||||
|
|
||||||
`=~`:idx:
|
`=~`:idx:
|
||||||
`pegs.html#138 <pegs.html#138>`_
|
`regexprs.html#111 <regexprs.html#111>`_
|
||||||
|
|
||||||
`=~`:idx:
|
`=~`:idx:
|
||||||
`regexprs.html#108 <regexprs.html#108>`_
|
`pegs.html#140 <pegs.html#140>`_
|
||||||
|
|
||||||
`>`:idx:
|
`>`:idx:
|
||||||
`system.html#349 <system.html#349>`_
|
`system.html#349 <system.html#349>`_
|
||||||
|
|
@ -234,14 +235,15 @@ Index
|
||||||
`pegs.html#110 <pegs.html#110>`_
|
`pegs.html#110 <pegs.html#110>`_
|
||||||
|
|
||||||
`@`:idx:
|
`@`:idx:
|
||||||
`system.html#357 <system.html#357>`_
|
* `system.html#357 <system.html#357>`_
|
||||||
|
* `pegs.html#112 <pegs.html#112>`_
|
||||||
`[]`:idx:
|
|
||||||
`strtabs.html#107 <strtabs.html#107>`_
|
|
||||||
|
|
||||||
`[]`:idx:
|
`[]`:idx:
|
||||||
`macros.html#112 <macros.html#112>`_
|
`macros.html#112 <macros.html#112>`_
|
||||||
|
|
||||||
|
`[]`:idx:
|
||||||
|
`strtabs.html#107 <strtabs.html#107>`_
|
||||||
|
|
||||||
`[]=`:idx:
|
`[]=`:idx:
|
||||||
`macros.html#113 <macros.html#113>`_
|
`macros.html#113 <macros.html#113>`_
|
||||||
|
|
||||||
|
|
@ -279,8 +281,8 @@ Index
|
||||||
* `system.html#368 <system.html#368>`_
|
* `system.html#368 <system.html#368>`_
|
||||||
* `system.html#369 <system.html#369>`_
|
* `system.html#369 <system.html#369>`_
|
||||||
* `parsesql.html#108 <parsesql.html#108>`_
|
* `parsesql.html#108 <parsesql.html#108>`_
|
||||||
* `macros.html#118 <macros.html#118>`_
|
|
||||||
* `macros.html#119 <macros.html#119>`_
|
* `macros.html#119 <macros.html#119>`_
|
||||||
|
* `macros.html#120 <macros.html#120>`_
|
||||||
|
|
||||||
`addf`:idx:
|
`addf`:idx:
|
||||||
`strutils.html#111 <strutils.html#111>`_
|
`strutils.html#111 <strutils.html#111>`_
|
||||||
|
|
@ -332,17 +334,17 @@ Index
|
||||||
* `system.html#241 <system.html#241>`_
|
* `system.html#241 <system.html#241>`_
|
||||||
|
|
||||||
`any`:idx:
|
`any`:idx:
|
||||||
`pegs.html#116 <pegs.html#116>`_
|
|
||||||
|
|
||||||
`any character`:idx:
|
|
||||||
`pegs.html#115 <pegs.html#115>`_
|
|
||||||
|
|
||||||
`any rune`:idx:
|
|
||||||
`pegs.html#117 <pegs.html#117>`_
|
`pegs.html#117 <pegs.html#117>`_
|
||||||
|
|
||||||
`anyRune`:idx:
|
`any character`:idx:
|
||||||
|
`pegs.html#116 <pegs.html#116>`_
|
||||||
|
|
||||||
|
`any rune`:idx:
|
||||||
`pegs.html#118 <pegs.html#118>`_
|
`pegs.html#118 <pegs.html#118>`_
|
||||||
|
|
||||||
|
`anyRune`:idx:
|
||||||
|
`pegs.html#119 <pegs.html#119>`_
|
||||||
|
|
||||||
`apostrophe`:idx:
|
`apostrophe`:idx:
|
||||||
`manual.html#129 <manual.html#129>`_
|
`manual.html#129 <manual.html#129>`_
|
||||||
|
|
||||||
|
|
@ -403,7 +405,8 @@ Index
|
||||||
`xmlgen.html#111 <xmlgen.html#111>`_
|
`xmlgen.html#111 <xmlgen.html#111>`_
|
||||||
|
|
||||||
`backslash`:idx:
|
`backslash`:idx:
|
||||||
`manual.html#127 <manual.html#127>`_
|
* `manual.html#127 <manual.html#127>`_
|
||||||
|
* `regexprs.html#101 <regexprs.html#101>`_
|
||||||
|
|
||||||
`backspace`:idx:
|
`backspace`:idx:
|
||||||
`manual.html#132 <manual.html#132>`_
|
`manual.html#132 <manual.html#132>`_
|
||||||
|
|
@ -476,7 +479,7 @@ Index
|
||||||
`xmlgen.html#118 <xmlgen.html#118>`_
|
`xmlgen.html#118 <xmlgen.html#118>`_
|
||||||
|
|
||||||
`capture`:idx:
|
`capture`:idx:
|
||||||
`pegs.html#121 <pegs.html#121>`_
|
`pegs.html#122 <pegs.html#122>`_
|
||||||
|
|
||||||
`card`:idx:
|
`card`:idx:
|
||||||
`system.html#175 <system.html#175>`_
|
`system.html#175 <system.html#175>`_
|
||||||
|
|
@ -695,12 +698,12 @@ Index
|
||||||
`CompileDate`:idx:
|
`CompileDate`:idx:
|
||||||
`system.html#390 <system.html#390>`_
|
`system.html#390 <system.html#390>`_
|
||||||
|
|
||||||
`CompileTime`:idx:
|
|
||||||
`system.html#391 <system.html#391>`_
|
|
||||||
|
|
||||||
`compileTime`:idx:
|
`compileTime`:idx:
|
||||||
`manual.html#229 <manual.html#229>`_
|
`manual.html#229 <manual.html#229>`_
|
||||||
|
|
||||||
|
`CompileTime`:idx:
|
||||||
|
`system.html#391 <system.html#391>`_
|
||||||
|
|
||||||
`complex statements`:idx:
|
`complex statements`:idx:
|
||||||
`manual.html#178 <manual.html#178>`_
|
`manual.html#178 <manual.html#178>`_
|
||||||
|
|
||||||
|
|
@ -719,8 +722,8 @@ Index
|
||||||
* `strutils.html#137 <strutils.html#137>`_
|
* `strutils.html#137 <strutils.html#137>`_
|
||||||
* `strutils.html#138 <strutils.html#138>`_
|
* `strutils.html#138 <strutils.html#138>`_
|
||||||
* `strutils.html#139 <strutils.html#139>`_
|
* `strutils.html#139 <strutils.html#139>`_
|
||||||
* `pegs.html#139 <pegs.html#139>`_
|
* `pegs.html#141 <pegs.html#141>`_
|
||||||
* `pegs.html#140 <pegs.html#140>`_
|
* `pegs.html#142 <pegs.html#142>`_
|
||||||
|
|
||||||
`continue`:idx:
|
`continue`:idx:
|
||||||
`manual.html#198 <manual.html#198>`_
|
`manual.html#198 <manual.html#198>`_
|
||||||
|
|
@ -736,10 +739,10 @@ Index
|
||||||
`system.html#407 <system.html#407>`_
|
`system.html#407 <system.html#407>`_
|
||||||
|
|
||||||
`copyNimNode`:idx:
|
`copyNimNode`:idx:
|
||||||
`macros.html#135 <macros.html#135>`_
|
`macros.html#136 <macros.html#136>`_
|
||||||
|
|
||||||
`copyNimTree`:idx:
|
`copyNimTree`:idx:
|
||||||
`macros.html#136 <macros.html#136>`_
|
`macros.html#137 <macros.html#137>`_
|
||||||
|
|
||||||
`coreAttr`:idx:
|
`coreAttr`:idx:
|
||||||
`xmlgen.html#103 <xmlgen.html#103>`_
|
`xmlgen.html#103 <xmlgen.html#103>`_
|
||||||
|
|
@ -1185,7 +1188,7 @@ Index
|
||||||
|
|
||||||
`del`:idx:
|
`del`:idx:
|
||||||
* `xmlgen.html#124 <xmlgen.html#124>`_
|
* `xmlgen.html#124 <xmlgen.html#124>`_
|
||||||
* `macros.html#120 <macros.html#120>`_
|
* `macros.html#121 <macros.html#121>`_
|
||||||
|
|
||||||
`delete`:idx:
|
`delete`:idx:
|
||||||
`strutils.html#156 <strutils.html#156>`_
|
`strutils.html#156 <strutils.html#156>`_
|
||||||
|
|
@ -1198,7 +1201,7 @@ Index
|
||||||
`xmlgen.html#125 <xmlgen.html#125>`_
|
`xmlgen.html#125 <xmlgen.html#125>`_
|
||||||
|
|
||||||
`digits`:idx:
|
`digits`:idx:
|
||||||
`pegs.html#125 <pegs.html#125>`_
|
`pegs.html#126 <pegs.html#126>`_
|
||||||
|
|
||||||
`Digits`:idx:
|
`Digits`:idx:
|
||||||
`strutils.html#104 <strutils.html#104>`_
|
`strutils.html#104 <strutils.html#104>`_
|
||||||
|
|
@ -1290,10 +1293,10 @@ Index
|
||||||
`system.html#160 <system.html#160>`_
|
`system.html#160 <system.html#160>`_
|
||||||
|
|
||||||
`EInvalidPeg`:idx:
|
`EInvalidPeg`:idx:
|
||||||
`pegs.html#149 <pegs.html#149>`_
|
`pegs.html#150 <pegs.html#150>`_
|
||||||
|
|
||||||
`EInvalidRegEx`:idx:
|
`EInvalidRegEx`:idx:
|
||||||
`regexprs.html#101 <regexprs.html#101>`_
|
`regexprs.html#104 <regexprs.html#104>`_
|
||||||
|
|
||||||
`EInvalidSql`:idx:
|
`EInvalidSql`:idx:
|
||||||
`parsesql.html#103 <parsesql.html#103>`_
|
`parsesql.html#103 <parsesql.html#103>`_
|
||||||
|
|
@ -1322,7 +1325,7 @@ Index
|
||||||
|
|
||||||
`endsWith`:idx:
|
`endsWith`:idx:
|
||||||
* `strutils.html#148 <strutils.html#148>`_
|
* `strutils.html#148 <strutils.html#148>`_
|
||||||
* `pegs.html#142 <pegs.html#142>`_
|
* `pegs.html#144 <pegs.html#144>`_
|
||||||
|
|
||||||
`ENoExceptionToReraise`:idx:
|
`ENoExceptionToReraise`:idx:
|
||||||
* `manual.html#187 <manual.html#187>`_
|
* `manual.html#187 <manual.html#187>`_
|
||||||
|
|
@ -1334,12 +1337,12 @@ Index
|
||||||
`enum_cursor_type`:idx:
|
`enum_cursor_type`:idx:
|
||||||
`mysql.html#237 <mysql.html#237>`_
|
`mysql.html#237 <mysql.html#237>`_
|
||||||
|
|
||||||
`Enumeration`:idx:
|
|
||||||
`manual.html#149 <manual.html#149>`_
|
|
||||||
|
|
||||||
`enumeration`:idx:
|
`enumeration`:idx:
|
||||||
`tut1.html#113 <tut1.html#113>`_
|
`tut1.html#113 <tut1.html#113>`_
|
||||||
|
|
||||||
|
`Enumeration`:idx:
|
||||||
|
`manual.html#149 <manual.html#149>`_
|
||||||
|
|
||||||
`enum_field_types`:idx:
|
`enum_field_types`:idx:
|
||||||
`mysql.html#202 <mysql.html#202>`_
|
`mysql.html#202 <mysql.html#202>`_
|
||||||
|
|
||||||
|
|
@ -1390,7 +1393,7 @@ Index
|
||||||
`error`:idx:
|
`error`:idx:
|
||||||
* `manual.html#226 <manual.html#226>`_
|
* `manual.html#226 <manual.html#226>`_
|
||||||
* `manual.html#230 <manual.html#230>`_
|
* `manual.html#230 <manual.html#230>`_
|
||||||
* `macros.html#137 <macros.html#137>`_
|
* `macros.html#138 <macros.html#138>`_
|
||||||
|
|
||||||
`errorMsg`:idx:
|
`errorMsg`:idx:
|
||||||
`parsexml.html#120 <parsexml.html#120>`_
|
`parsexml.html#120 <parsexml.html#120>`_
|
||||||
|
|
@ -1478,13 +1481,13 @@ Index
|
||||||
`os.html#132 <os.html#132>`_
|
`os.html#132 <os.html#132>`_
|
||||||
|
|
||||||
`expectKind`:idx:
|
`expectKind`:idx:
|
||||||
`macros.html#146 <macros.html#146>`_
|
`macros.html#147 <macros.html#147>`_
|
||||||
|
|
||||||
`expectLen`:idx:
|
`expectLen`:idx:
|
||||||
`macros.html#148 <macros.html#148>`_
|
`macros.html#149 <macros.html#149>`_
|
||||||
|
|
||||||
`expectMinLen`:idx:
|
`expectMinLen`:idx:
|
||||||
`macros.html#147 <macros.html#147>`_
|
`macros.html#148 <macros.html#148>`_
|
||||||
|
|
||||||
`exportc`:idx:
|
`exportc`:idx:
|
||||||
`nimrodc.html#102 <nimrodc.html#102>`_
|
`nimrodc.html#102 <nimrodc.html#102>`_
|
||||||
|
|
@ -1632,10 +1635,10 @@ Index
|
||||||
* `strutils.html#119 <strutils.html#119>`_
|
* `strutils.html#119 <strutils.html#119>`_
|
||||||
* `strutils.html#120 <strutils.html#120>`_
|
* `strutils.html#120 <strutils.html#120>`_
|
||||||
* `strutils.html#121 <strutils.html#121>`_
|
* `strutils.html#121 <strutils.html#121>`_
|
||||||
* `regexprs.html#106 <regexprs.html#106>`_
|
* `regexprs.html#109 <regexprs.html#109>`_
|
||||||
* `regexprs.html#107 <regexprs.html#107>`_
|
* `regexprs.html#110 <regexprs.html#110>`_
|
||||||
* `pegs.html#136 <pegs.html#136>`_
|
* `pegs.html#138 <pegs.html#138>`_
|
||||||
* `pegs.html#137 <pegs.html#137>`_
|
* `pegs.html#139 <pegs.html#139>`_
|
||||||
|
|
||||||
`float`:idx:
|
`float`:idx:
|
||||||
`system.html#106 <system.html#106>`_
|
`system.html#106 <system.html#106>`_
|
||||||
|
|
@ -1647,10 +1650,10 @@ Index
|
||||||
`system.html#108 <system.html#108>`_
|
`system.html#108 <system.html#108>`_
|
||||||
|
|
||||||
`floatVal`:idx:
|
`floatVal`:idx:
|
||||||
`macros.html#123 <macros.html#123>`_
|
`macros.html#124 <macros.html#124>`_
|
||||||
|
|
||||||
`floatVal=`:idx:
|
`floatVal=`:idx:
|
||||||
`macros.html#129 <macros.html#129>`_
|
`macros.html#130 <macros.html#130>`_
|
||||||
|
|
||||||
`FlushFile`:idx:
|
`FlushFile`:idx:
|
||||||
`system.html#503 <system.html#503>`_
|
`system.html#503 <system.html#503>`_
|
||||||
|
|
@ -1715,6 +1718,9 @@ Index
|
||||||
`generalized raw string literal`:idx:
|
`generalized raw string literal`:idx:
|
||||||
`manual.html#136 <manual.html#136>`_
|
`manual.html#136 <manual.html#136>`_
|
||||||
|
|
||||||
|
`generic character types`:idx:
|
||||||
|
`regexprs.html#102 <regexprs.html#102>`_
|
||||||
|
|
||||||
`Generics`:idx:
|
`Generics`:idx:
|
||||||
* `manual.html#212 <manual.html#212>`_
|
* `manual.html#212 <manual.html#212>`_
|
||||||
* `tut2.html#109 <tut2.html#109>`_
|
* `tut2.html#109 <tut2.html#109>`_
|
||||||
|
|
@ -1987,7 +1993,7 @@ Index
|
||||||
`hint`:idx:
|
`hint`:idx:
|
||||||
* `manual.html#224 <manual.html#224>`_
|
* `manual.html#224 <manual.html#224>`_
|
||||||
* `manual.html#233 <manual.html#233>`_
|
* `manual.html#233 <manual.html#233>`_
|
||||||
* `macros.html#139 <macros.html#139>`_
|
* `macros.html#140 <macros.html#140>`_
|
||||||
|
|
||||||
`hostCPU`:idx:
|
`hostCPU`:idx:
|
||||||
`system.html#398 <system.html#398>`_
|
`system.html#398 <system.html#398>`_
|
||||||
|
|
@ -2001,13 +2007,13 @@ Index
|
||||||
`hr`:idx:
|
`hr`:idx:
|
||||||
`xmlgen.html#140 <xmlgen.html#140>`_
|
`xmlgen.html#140 <xmlgen.html#140>`_
|
||||||
|
|
||||||
|
`html`:idx:
|
||||||
|
`xmlgen.html#139 <xmlgen.html#139>`_
|
||||||
|
|
||||||
`HTML`:idx:
|
`HTML`:idx:
|
||||||
* `parsexml.html#102 <parsexml.html#102>`_
|
* `parsexml.html#102 <parsexml.html#102>`_
|
||||||
* `xmlgen.html#102 <xmlgen.html#102>`_
|
* `xmlgen.html#102 <xmlgen.html#102>`_
|
||||||
|
|
||||||
`html`:idx:
|
|
||||||
`xmlgen.html#139 <xmlgen.html#139>`_
|
|
||||||
|
|
||||||
`HTTPPOST_BUFFER`:idx:
|
`HTTPPOST_BUFFER`:idx:
|
||||||
`libcurl.html#266 <libcurl.html#266>`_
|
`libcurl.html#266 <libcurl.html#266>`_
|
||||||
|
|
||||||
|
|
@ -2033,14 +2039,14 @@ Index
|
||||||
`xmlgen.html#141 <xmlgen.html#141>`_
|
`xmlgen.html#141 <xmlgen.html#141>`_
|
||||||
|
|
||||||
`ident`:idx:
|
`ident`:idx:
|
||||||
* `pegs.html#129 <pegs.html#129>`_
|
* `pegs.html#130 <pegs.html#130>`_
|
||||||
* `macros.html#125 <macros.html#125>`_
|
* `macros.html#126 <macros.html#126>`_
|
||||||
|
|
||||||
`ident=`:idx:
|
`ident=`:idx:
|
||||||
`macros.html#131 <macros.html#131>`_
|
`macros.html#132 <macros.html#132>`_
|
||||||
|
|
||||||
`identChars`:idx:
|
`identChars`:idx:
|
||||||
`pegs.html#127 <pegs.html#127>`_
|
`pegs.html#128 <pegs.html#128>`_
|
||||||
|
|
||||||
`IdentChars`:idx:
|
`IdentChars`:idx:
|
||||||
`strutils.html#105 <strutils.html#105>`_
|
`strutils.html#105 <strutils.html#105>`_
|
||||||
|
|
@ -2052,7 +2058,7 @@ Index
|
||||||
`manual.html#116 <manual.html#116>`_
|
`manual.html#116 <manual.html#116>`_
|
||||||
|
|
||||||
`identStartChars`:idx:
|
`identStartChars`:idx:
|
||||||
`pegs.html#128 <pegs.html#128>`_
|
`pegs.html#129 <pegs.html#129>`_
|
||||||
|
|
||||||
`IdentStartChars`:idx:
|
`IdentStartChars`:idx:
|
||||||
`strutils.html#106 <strutils.html#106>`_
|
`strutils.html#106 <strutils.html#106>`_
|
||||||
|
|
@ -2138,10 +2144,10 @@ Index
|
||||||
`strutils.html#141 <strutils.html#141>`_
|
`strutils.html#141 <strutils.html#141>`_
|
||||||
|
|
||||||
`intVal`:idx:
|
`intVal`:idx:
|
||||||
`macros.html#122 <macros.html#122>`_
|
`macros.html#123 <macros.html#123>`_
|
||||||
|
|
||||||
`intVal=`:idx:
|
`intVal=`:idx:
|
||||||
`macros.html#128 <macros.html#128>`_
|
`macros.html#129 <macros.html#129>`_
|
||||||
|
|
||||||
`is`:idx:
|
`is`:idx:
|
||||||
`system.html#353 <system.html#353>`_
|
`system.html#353 <system.html#353>`_
|
||||||
|
|
@ -2226,7 +2232,7 @@ Index
|
||||||
|
|
||||||
`kind`:idx:
|
`kind`:idx:
|
||||||
* `parsexml.html#110 <parsexml.html#110>`_
|
* `parsexml.html#110 <parsexml.html#110>`_
|
||||||
* `macros.html#121 <macros.html#121>`_
|
* `macros.html#122 <macros.html#122>`_
|
||||||
|
|
||||||
`l-values`:idx:
|
`l-values`:idx:
|
||||||
`manual.html#107 <manual.html#107>`_
|
`manual.html#107 <manual.html#107>`_
|
||||||
|
|
@ -2245,13 +2251,13 @@ Index
|
||||||
* `system.html#172 <system.html#172>`_
|
* `system.html#172 <system.html#172>`_
|
||||||
* `strtabs.html#109 <strtabs.html#109>`_
|
* `strtabs.html#109 <strtabs.html#109>`_
|
||||||
* `parsesql.html#107 <parsesql.html#107>`_
|
* `parsesql.html#107 <parsesql.html#107>`_
|
||||||
* `macros.html#117 <macros.html#117>`_
|
* `macros.html#118 <macros.html#118>`_
|
||||||
|
|
||||||
`Letters`:idx:
|
`Letters`:idx:
|
||||||
`strutils.html#103 <strutils.html#103>`_
|
`strutils.html#103 <strutils.html#103>`_
|
||||||
|
|
||||||
`letters`:idx:
|
`letters`:idx:
|
||||||
`pegs.html#124 <pegs.html#124>`_
|
`pegs.html#125 <pegs.html#125>`_
|
||||||
|
|
||||||
`li`:idx:
|
`li`:idx:
|
||||||
`xmlgen.html#148 <xmlgen.html#148>`_
|
`xmlgen.html#148 <xmlgen.html#148>`_
|
||||||
|
|
@ -2353,16 +2359,16 @@ Index
|
||||||
`xmlgen.html#150 <xmlgen.html#150>`_
|
`xmlgen.html#150 <xmlgen.html#150>`_
|
||||||
|
|
||||||
`match`:idx:
|
`match`:idx:
|
||||||
* `regexprs.html#103 <regexprs.html#103>`_
|
* `regexprs.html#106 <regexprs.html#106>`_
|
||||||
* `regexprs.html#104 <regexprs.html#104>`_
|
* `regexprs.html#107 <regexprs.html#107>`_
|
||||||
* `pegs.html#132 <pegs.html#132>`_
|
|
||||||
* `pegs.html#133 <pegs.html#133>`_
|
|
||||||
|
|
||||||
`matchLen`:idx:
|
|
||||||
* `regexprs.html#105 <regexprs.html#105>`_
|
|
||||||
* `pegs.html#134 <pegs.html#134>`_
|
* `pegs.html#134 <pegs.html#134>`_
|
||||||
* `pegs.html#135 <pegs.html#135>`_
|
* `pegs.html#135 <pegs.html#135>`_
|
||||||
|
|
||||||
|
`matchLen`:idx:
|
||||||
|
* `regexprs.html#108 <regexprs.html#108>`_
|
||||||
|
* `pegs.html#136 <pegs.html#136>`_
|
||||||
|
* `pegs.html#137 <pegs.html#137>`_
|
||||||
|
|
||||||
`max`:idx:
|
`max`:idx:
|
||||||
* `system.html#318 <system.html#318>`_
|
* `system.html#318 <system.html#318>`_
|
||||||
* `system.html#444 <system.html#444>`_
|
* `system.html#444 <system.html#444>`_
|
||||||
|
|
@ -2397,8 +2403,8 @@ Index
|
||||||
`mysql.html#191 <mysql.html#191>`_
|
`mysql.html#191 <mysql.html#191>`_
|
||||||
|
|
||||||
`MaxSubpatterns`:idx:
|
`MaxSubpatterns`:idx:
|
||||||
* `regexprs.html#102 <regexprs.html#102>`_
|
* `regexprs.html#105 <regexprs.html#105>`_
|
||||||
* `pegs.html#131 <pegs.html#131>`_
|
* `pegs.html#132 <pegs.html#132>`_
|
||||||
|
|
||||||
`MAX_TINYINT_WIDTH`:idx:
|
`MAX_TINYINT_WIDTH`:idx:
|
||||||
`mysql.html#190 <mysql.html#190>`_
|
`mysql.html#190 <mysql.html#190>`_
|
||||||
|
|
@ -2990,13 +2996,13 @@ Index
|
||||||
`system.html#134 <system.html#134>`_
|
`system.html#134 <system.html#134>`_
|
||||||
|
|
||||||
`natural`:idx:
|
`natural`:idx:
|
||||||
`pegs.html#130 <pegs.html#130>`_
|
`pegs.html#131 <pegs.html#131>`_
|
||||||
|
|
||||||
`neginf`:idx:
|
`neginf`:idx:
|
||||||
`system.html#430 <system.html#430>`_
|
`system.html#430 <system.html#430>`_
|
||||||
|
|
||||||
`nestList`:idx:
|
`nestList`:idx:
|
||||||
`macros.html#151 <macros.html#151>`_
|
`macros.html#152 <macros.html#152>`_
|
||||||
|
|
||||||
`NET`:idx:
|
`NET`:idx:
|
||||||
`mysql.html#199 <mysql.html#199>`_
|
`mysql.html#199 <mysql.html#199>`_
|
||||||
|
|
@ -3042,38 +3048,38 @@ Index
|
||||||
* `system.html#125 <system.html#125>`_
|
* `system.html#125 <system.html#125>`_
|
||||||
|
|
||||||
`newCall`:idx:
|
`newCall`:idx:
|
||||||
* `macros.html#149 <macros.html#149>`_
|
|
||||||
* `macros.html#150 <macros.html#150>`_
|
* `macros.html#150 <macros.html#150>`_
|
||||||
|
* `macros.html#151 <macros.html#151>`_
|
||||||
|
|
||||||
`newFileStream`:idx:
|
`newFileStream`:idx:
|
||||||
* `streams.html#120 <streams.html#120>`_
|
* `streams.html#120 <streams.html#120>`_
|
||||||
* `streams.html#121 <streams.html#121>`_
|
* `streams.html#121 <streams.html#121>`_
|
||||||
|
|
||||||
`newFloatLitNode`:idx:
|
`newFloatLitNode`:idx:
|
||||||
`macros.html#142 <macros.html#142>`_
|
`macros.html#143 <macros.html#143>`_
|
||||||
|
|
||||||
`newIdentNode`:idx:
|
`newIdentNode`:idx:
|
||||||
* `macros.html#143 <macros.html#143>`_
|
|
||||||
* `macros.html#144 <macros.html#144>`_
|
* `macros.html#144 <macros.html#144>`_
|
||||||
|
* `macros.html#145 <macros.html#145>`_
|
||||||
|
|
||||||
`newIntLitNode`:idx:
|
`newIntLitNode`:idx:
|
||||||
`macros.html#141 <macros.html#141>`_
|
`macros.html#142 <macros.html#142>`_
|
||||||
|
|
||||||
|
`newLine`:idx:
|
||||||
|
`pegs.html#121 <pegs.html#121>`_
|
||||||
|
|
||||||
`newline`:idx:
|
`newline`:idx:
|
||||||
* `manual.html#121 <manual.html#121>`_
|
* `manual.html#121 <manual.html#121>`_
|
||||||
* `pegs.html#119 <pegs.html#119>`_
|
* `pegs.html#120 <pegs.html#120>`_
|
||||||
|
|
||||||
`newLine`:idx:
|
|
||||||
`pegs.html#120 <pegs.html#120>`_
|
|
||||||
|
|
||||||
`NewLines`:idx:
|
`NewLines`:idx:
|
||||||
`lexbase.html#102 <lexbase.html#102>`_
|
`lexbase.html#102 <lexbase.html#102>`_
|
||||||
|
|
||||||
`newNimNode`:idx:
|
`newNimNode`:idx:
|
||||||
`macros.html#134 <macros.html#134>`_
|
`macros.html#135 <macros.html#135>`_
|
||||||
|
|
||||||
`newNonTerminal`:idx:
|
`newNonTerminal`:idx:
|
||||||
`pegs.html#123 <pegs.html#123>`_
|
`pegs.html#124 <pegs.html#124>`_
|
||||||
|
|
||||||
`newSeq`:idx:
|
`newSeq`:idx:
|
||||||
`system.html#167 <system.html#167>`_
|
`system.html#167 <system.html#167>`_
|
||||||
|
|
@ -3089,7 +3095,7 @@ Index
|
||||||
* `strtabs.html#105 <strtabs.html#105>`_
|
* `strtabs.html#105 <strtabs.html#105>`_
|
||||||
|
|
||||||
`newStrLitNode`:idx:
|
`newStrLitNode`:idx:
|
||||||
`macros.html#140 <macros.html#140>`_
|
`macros.html#141 <macros.html#141>`_
|
||||||
|
|
||||||
`next`:idx:
|
`next`:idx:
|
||||||
* `parseopt.html#105 <parseopt.html#105>`_
|
* `parseopt.html#105 <parseopt.html#105>`_
|
||||||
|
|
@ -3124,7 +3130,7 @@ Index
|
||||||
`mysql.html#136 <mysql.html#136>`_
|
`mysql.html#136 <mysql.html#136>`_
|
||||||
|
|
||||||
`nonterminal`:idx:
|
`nonterminal`:idx:
|
||||||
`pegs.html#122 <pegs.html#122>`_
|
`pegs.html#123 <pegs.html#123>`_
|
||||||
|
|
||||||
`normalize`:idx:
|
`normalize`:idx:
|
||||||
`strutils.html#118 <strutils.html#118>`_
|
`strutils.html#118 <strutils.html#118>`_
|
||||||
|
|
@ -3238,7 +3244,7 @@ Index
|
||||||
`strtabs.html#110 <strtabs.html#110>`_
|
`strtabs.html#110 <strtabs.html#110>`_
|
||||||
|
|
||||||
`parallelReplace`:idx:
|
`parallelReplace`:idx:
|
||||||
`pegs.html#144 <pegs.html#144>`_
|
`pegs.html#146 <pegs.html#146>`_
|
||||||
|
|
||||||
`param`:idx:
|
`param`:idx:
|
||||||
`xmlgen.html#158 <xmlgen.html#158>`_
|
`xmlgen.html#158 <xmlgen.html#158>`_
|
||||||
|
|
@ -3268,7 +3274,7 @@ Index
|
||||||
`strutils.html#142 <strutils.html#142>`_
|
`strutils.html#142 <strutils.html#142>`_
|
||||||
|
|
||||||
`parsePeg`:idx:
|
`parsePeg`:idx:
|
||||||
`pegs.html#150 <pegs.html#150>`_
|
`pegs.html#151 <pegs.html#151>`_
|
||||||
|
|
||||||
`parseSQL`:idx:
|
`parseSQL`:idx:
|
||||||
`parsesql.html#109 <parsesql.html#109>`_
|
`parsesql.html#109 <parsesql.html#109>`_
|
||||||
|
|
@ -3403,7 +3409,7 @@ Index
|
||||||
`libcurl.html#122 <libcurl.html#122>`_
|
`libcurl.html#122 <libcurl.html#122>`_
|
||||||
|
|
||||||
`peg`:idx:
|
`peg`:idx:
|
||||||
`pegs.html#151 <pegs.html#151>`_
|
`pegs.html#152 <pegs.html#152>`_
|
||||||
|
|
||||||
`Pfd_set`:idx:
|
`Pfd_set`:idx:
|
||||||
`libcurl.html#138 <libcurl.html#138>`_
|
`libcurl.html#138 <libcurl.html#138>`_
|
||||||
|
|
@ -3771,16 +3777,16 @@ Index
|
||||||
`system.html#412 <system.html#412>`_
|
`system.html#412 <system.html#412>`_
|
||||||
|
|
||||||
`reBinary`:idx:
|
`reBinary`:idx:
|
||||||
`regexprs.html#113 <regexprs.html#113>`_
|
`regexprs.html#116 <regexprs.html#116>`_
|
||||||
|
|
||||||
`Recursive module dependancies`:idx:
|
`Recursive module dependancies`:idx:
|
||||||
`manual.html#221 <manual.html#221>`_
|
`manual.html#221 <manual.html#221>`_
|
||||||
|
|
||||||
`reEmail`:idx:
|
`reEmail`:idx:
|
||||||
`regexprs.html#116 <regexprs.html#116>`_
|
`regexprs.html#119 <regexprs.html#119>`_
|
||||||
|
|
||||||
`reFloat`:idx:
|
`reFloat`:idx:
|
||||||
`regexprs.html#115 <regexprs.html#115>`_
|
`regexprs.html#118 <regexprs.html#118>`_
|
||||||
|
|
||||||
`REFRESH_DES_KEY_FILE`:idx:
|
`REFRESH_DES_KEY_FILE`:idx:
|
||||||
`mysql.html#154 <mysql.html#154>`_
|
`mysql.html#154 <mysql.html#154>`_
|
||||||
|
|
@ -3828,13 +3834,13 @@ Index
|
||||||
`nimrodc.html#112 <nimrodc.html#112>`_
|
`nimrodc.html#112 <nimrodc.html#112>`_
|
||||||
|
|
||||||
`reHex`:idx:
|
`reHex`:idx:
|
||||||
`regexprs.html#112 <regexprs.html#112>`_
|
`regexprs.html#115 <regexprs.html#115>`_
|
||||||
|
|
||||||
`reIdentifier`:idx:
|
`reIdentifier`:idx:
|
||||||
`regexprs.html#109 <regexprs.html#109>`_
|
`regexprs.html#112 <regexprs.html#112>`_
|
||||||
|
|
||||||
`reInteger`:idx:
|
`reInteger`:idx:
|
||||||
`regexprs.html#111 <regexprs.html#111>`_
|
`regexprs.html#114 <regexprs.html#114>`_
|
||||||
|
|
||||||
`removeDir`:idx:
|
`removeDir`:idx:
|
||||||
`os.html#158 <os.html#158>`_
|
`os.html#158 <os.html#158>`_
|
||||||
|
|
@ -3843,13 +3849,13 @@ Index
|
||||||
`os.html#144 <os.html#144>`_
|
`os.html#144 <os.html#144>`_
|
||||||
|
|
||||||
`reNatural`:idx:
|
`reNatural`:idx:
|
||||||
`regexprs.html#110 <regexprs.html#110>`_
|
`regexprs.html#113 <regexprs.html#113>`_
|
||||||
|
|
||||||
`renderSQL`:idx:
|
`renderSQL`:idx:
|
||||||
`parsesql.html#110 <parsesql.html#110>`_
|
`parsesql.html#110 <parsesql.html#110>`_
|
||||||
|
|
||||||
`reOctal`:idx:
|
`reOctal`:idx:
|
||||||
`regexprs.html#114 <regexprs.html#114>`_
|
`regexprs.html#117 <regexprs.html#117>`_
|
||||||
|
|
||||||
`repeatChar`:idx:
|
`repeatChar`:idx:
|
||||||
`strutils.html#146 <strutils.html#146>`_
|
`strutils.html#146 <strutils.html#146>`_
|
||||||
|
|
@ -3857,7 +3863,7 @@ Index
|
||||||
`replace`:idx:
|
`replace`:idx:
|
||||||
* `strutils.html#154 <strutils.html#154>`_
|
* `strutils.html#154 <strutils.html#154>`_
|
||||||
* `strutils.html#155 <strutils.html#155>`_
|
* `strutils.html#155 <strutils.html#155>`_
|
||||||
* `pegs.html#143 <pegs.html#143>`_
|
* `pegs.html#145 <pegs.html#145>`_
|
||||||
|
|
||||||
`replaceStr`:idx:
|
`replaceStr`:idx:
|
||||||
* `strutils.html#122 <strutils.html#122>`_
|
* `strutils.html#122 <strutils.html#122>`_
|
||||||
|
|
@ -3880,7 +3886,7 @@ Index
|
||||||
`manual.html#192 <manual.html#192>`_
|
`manual.html#192 <manual.html#192>`_
|
||||||
|
|
||||||
`reURL`:idx:
|
`reURL`:idx:
|
||||||
`regexprs.html#117 <regexprs.html#117>`_
|
`regexprs.html#120 <regexprs.html#120>`_
|
||||||
|
|
||||||
`round`:idx:
|
`round`:idx:
|
||||||
`math.html#121 <math.html#121>`_
|
`math.html#121 <math.html#121>`_
|
||||||
|
|
@ -4048,6 +4054,9 @@ Index
|
||||||
* `system.html#230 <system.html#230>`_
|
* `system.html#230 <system.html#230>`_
|
||||||
* `system.html#231 <system.html#231>`_
|
* `system.html#231 <system.html#231>`_
|
||||||
|
|
||||||
|
`simple assertions`:idx:
|
||||||
|
`regexprs.html#103 <regexprs.html#103>`_
|
||||||
|
|
||||||
`simple statements`:idx:
|
`simple statements`:idx:
|
||||||
`manual.html#177 <manual.html#177>`_
|
`manual.html#177 <manual.html#177>`_
|
||||||
|
|
||||||
|
|
@ -4074,8 +4083,8 @@ Index
|
||||||
* `strutils.html#127 <strutils.html#127>`_
|
* `strutils.html#127 <strutils.html#127>`_
|
||||||
* `strutils.html#133 <strutils.html#133>`_
|
* `strutils.html#133 <strutils.html#133>`_
|
||||||
* `strutils.html#134 <strutils.html#134>`_
|
* `strutils.html#134 <strutils.html#134>`_
|
||||||
* `pegs.html#146 <pegs.html#146>`_
|
* `pegs.html#148 <pegs.html#148>`_
|
||||||
* `pegs.html#147 <pegs.html#147>`_
|
* `pegs.html#149 <pegs.html#149>`_
|
||||||
|
|
||||||
`splitFile`:idx:
|
`splitFile`:idx:
|
||||||
`os.html#129 <os.html#129>`_
|
`os.html#129 <os.html#129>`_
|
||||||
|
|
@ -4611,7 +4620,7 @@ Index
|
||||||
|
|
||||||
`startsWith`:idx:
|
`startsWith`:idx:
|
||||||
* `strutils.html#147 <strutils.html#147>`_
|
* `strutils.html#147 <strutils.html#147>`_
|
||||||
* `pegs.html#141 <pegs.html#141>`_
|
* `pegs.html#143 <pegs.html#143>`_
|
||||||
|
|
||||||
`statement macros`:idx:
|
`statement macros`:idx:
|
||||||
`tut2.html#112 <tut2.html#112>`_
|
`tut2.html#112 <tut2.html#112>`_
|
||||||
|
|
@ -4702,10 +4711,10 @@ Index
|
||||||
`manual.html#152 <manual.html#152>`_
|
`manual.html#152 <manual.html#152>`_
|
||||||
|
|
||||||
`strVal`:idx:
|
`strVal`:idx:
|
||||||
`macros.html#127 <macros.html#127>`_
|
`macros.html#128 <macros.html#128>`_
|
||||||
|
|
||||||
`strVal=`:idx:
|
`strVal=`:idx:
|
||||||
`macros.html#133 <macros.html#133>`_
|
`macros.html#134 <macros.html#134>`_
|
||||||
|
|
||||||
`st_udf_args`:idx:
|
`st_udf_args`:idx:
|
||||||
`mysql.html#258 <mysql.html#258>`_
|
`mysql.html#258 <mysql.html#258>`_
|
||||||
|
|
@ -4751,10 +4760,10 @@ Index
|
||||||
`dynlib.html#104 <dynlib.html#104>`_
|
`dynlib.html#104 <dynlib.html#104>`_
|
||||||
|
|
||||||
`symbol`:idx:
|
`symbol`:idx:
|
||||||
`macros.html#124 <macros.html#124>`_
|
`macros.html#125 <macros.html#125>`_
|
||||||
|
|
||||||
`symbol=`:idx:
|
`symbol=`:idx:
|
||||||
`macros.html#130 <macros.html#130>`_
|
`macros.html#131 <macros.html#131>`_
|
||||||
|
|
||||||
`syscall`:idx:
|
`syscall`:idx:
|
||||||
`manual.html#172 <manual.html#172>`_
|
`manual.html#172 <manual.html#172>`_
|
||||||
|
|
@ -5114,7 +5123,7 @@ Index
|
||||||
`strutils.html#145 <strutils.html#145>`_
|
`strutils.html#145 <strutils.html#145>`_
|
||||||
|
|
||||||
`toStrLit`:idx:
|
`toStrLit`:idx:
|
||||||
`macros.html#145 <macros.html#145>`_
|
`macros.html#146 <macros.html#146>`_
|
||||||
|
|
||||||
`toTitle`:idx:
|
`toTitle`:idx:
|
||||||
`unicode.html#113 <unicode.html#113>`_
|
`unicode.html#113 <unicode.html#113>`_
|
||||||
|
|
@ -5153,7 +5162,7 @@ Index
|
||||||
* `tut1.html#121 <tut1.html#121>`_
|
* `tut1.html#121 <tut1.html#121>`_
|
||||||
|
|
||||||
`transformFile`:idx:
|
`transformFile`:idx:
|
||||||
`pegs.html#145 <pegs.html#145>`_
|
`pegs.html#147 <pegs.html#147>`_
|
||||||
|
|
||||||
`TRequestMethod`:idx:
|
`TRequestMethod`:idx:
|
||||||
`cgi.html#105 <cgi.html#105>`_
|
`cgi.html#105 <cgi.html#105>`_
|
||||||
|
|
@ -5244,10 +5253,10 @@ Index
|
||||||
`parsexml.html#106 <parsexml.html#106>`_
|
`parsexml.html#106 <parsexml.html#106>`_
|
||||||
|
|
||||||
`typ`:idx:
|
`typ`:idx:
|
||||||
`macros.html#126 <macros.html#126>`_
|
`macros.html#127 <macros.html#127>`_
|
||||||
|
|
||||||
`typ=`:idx:
|
`typ=`:idx:
|
||||||
`macros.html#132 <macros.html#132>`_
|
`macros.html#133 <macros.html#133>`_
|
||||||
|
|
||||||
`type`:idx:
|
`type`:idx:
|
||||||
* `manual.html#102 <manual.html#102>`_
|
* `manual.html#102 <manual.html#102>`_
|
||||||
|
|
@ -5363,7 +5372,7 @@ Index
|
||||||
* `tut2.html#103 <tut2.html#103>`_
|
* `tut2.html#103 <tut2.html#103>`_
|
||||||
|
|
||||||
`verbose`:idx:
|
`verbose`:idx:
|
||||||
`regexprs.html#118 <regexprs.html#118>`_
|
`regexprs.html#121 <regexprs.html#121>`_
|
||||||
|
|
||||||
`vertical tabulator`:idx:
|
`vertical tabulator`:idx:
|
||||||
`manual.html#126 <manual.html#126>`_
|
`manual.html#126 <manual.html#126>`_
|
||||||
|
|
@ -5387,7 +5396,7 @@ Index
|
||||||
`warning`:idx:
|
`warning`:idx:
|
||||||
* `manual.html#225 <manual.html#225>`_
|
* `manual.html#225 <manual.html#225>`_
|
||||||
* `manual.html#232 <manual.html#232>`_
|
* `manual.html#232 <manual.html#232>`_
|
||||||
* `macros.html#138 <macros.html#138>`_
|
* `macros.html#139 <macros.html#139>`_
|
||||||
|
|
||||||
`when`:idx:
|
`when`:idx:
|
||||||
* `manual.html#185 <manual.html#185>`_
|
* `manual.html#185 <manual.html#185>`_
|
||||||
|
|
@ -5400,7 +5409,7 @@ Index
|
||||||
`strutils.html#102 <strutils.html#102>`_
|
`strutils.html#102 <strutils.html#102>`_
|
||||||
|
|
||||||
`whitespace`:idx:
|
`whitespace`:idx:
|
||||||
`pegs.html#126 <pegs.html#126>`_
|
`pegs.html#127 <pegs.html#127>`_
|
||||||
|
|
||||||
`winTimeToUnixTime`:idx:
|
`winTimeToUnixTime`:idx:
|
||||||
`times.html#118 <times.html#118>`_
|
`times.html#118 <times.html#118>`_
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ type
|
||||||
pkSequence, ## a b c ... --> Internal DSL: peg(a, b, c)
|
pkSequence, ## a b c ... --> Internal DSL: peg(a, b, c)
|
||||||
pkOrderedChoice, ## a / b / ... --> Internal DSL: a / b or /[a, b, c]
|
pkOrderedChoice, ## a / b / ... --> Internal DSL: a / b or /[a, b, c]
|
||||||
pkGreedyRep, ## a* --> Internal DSL: *a
|
pkGreedyRep, ## a* --> Internal DSL: *a
|
||||||
## a+ --> Internal DSL: +a; represented as (a a*)
|
## a+ --> (a a*)
|
||||||
pkGreedyRepChar, ## x* where x is a single character (superop)
|
pkGreedyRepChar, ## x* where x is a single character (superop)
|
||||||
pkGreedyRepSet, ## [set]* (superop)
|
pkGreedyRepSet, ## [set]* (superop)
|
||||||
pkGreedyAny, ## .* or _* (superop)
|
pkGreedyAny, ## .* or _* (superop)
|
||||||
|
|
@ -50,6 +50,7 @@ type
|
||||||
pkAndPredicate, ## &a --> Internal DSL: &a
|
pkAndPredicate, ## &a --> Internal DSL: &a
|
||||||
pkNotPredicate, ## !a --> Internal DSL: !a
|
pkNotPredicate, ## !a --> Internal DSL: !a
|
||||||
pkCapture, ## {a} --> Internal DSL: capture(a)
|
pkCapture, ## {a} --> Internal DSL: capture(a)
|
||||||
|
pkSearch, ## @a --> Internal DSL: @a
|
||||||
pkRule, ## a <- b
|
pkRule, ## a <- b
|
||||||
pkList ## a, b
|
pkList ## a, b
|
||||||
TNonTerminalFlag = enum
|
TNonTerminalFlag = enum
|
||||||
|
|
@ -175,6 +176,23 @@ proc `*`*(a: TPeg): TPeg =
|
||||||
result.kind = pkGreedyRep
|
result.kind = pkGreedyRep
|
||||||
result.sons = @[a]
|
result.sons = @[a]
|
||||||
|
|
||||||
|
proc `@`*(a: TPeg): TPeg =
|
||||||
|
## constructs a "search" for the PEG `a`
|
||||||
|
result.kind = pkSearch
|
||||||
|
result.sons = @[a]
|
||||||
|
|
||||||
|
when false:
|
||||||
|
proc contains(a: TPeg, k: TPegKind): bool =
|
||||||
|
if a.kind == k: return true
|
||||||
|
case a.kind
|
||||||
|
of pkEmpty, pkAny, pkAnyRune, pkGreedyAny, pkNewLine, pkTerminal,
|
||||||
|
pkTerminalIgnoreCase, pkTerminalIgnoreStyle, pkChar, pkGreedyRepChar,
|
||||||
|
pkCharChoice, pkGreedyRepSet: nil
|
||||||
|
of pkNonTerminal: return true
|
||||||
|
else:
|
||||||
|
for i in 0..a.sons.len-1:
|
||||||
|
if contains(a.sons[i], k): return true
|
||||||
|
|
||||||
proc `+`*(a: TPeg): TPeg =
|
proc `+`*(a: TPeg): TPeg =
|
||||||
## constructs a "greedy positive repetition" with the PEG `a`
|
## constructs a "greedy positive repetition" with the PEG `a`
|
||||||
return sequence(a, *a)
|
return sequence(a, *a)
|
||||||
|
|
@ -271,6 +289,125 @@ const
|
||||||
MaxSubpatterns* = 10 ## defines the maximum number of subpatterns that
|
MaxSubpatterns* = 10 ## defines the maximum number of subpatterns that
|
||||||
## can be captured. More subpatterns cannot be captured!
|
## can be captured. More subpatterns cannot be captured!
|
||||||
|
|
||||||
|
# ------------------------- debugging -----------------------------------------
|
||||||
|
|
||||||
|
proc esc(c: char, reserved = {'\0'..'\255'}): string =
|
||||||
|
case c
|
||||||
|
of '\b': result = "\\b"
|
||||||
|
of '\t': result = "\\t"
|
||||||
|
of '\c': result = "\\c"
|
||||||
|
of '\L': result = "\\l"
|
||||||
|
of '\v': result = "\\v"
|
||||||
|
of '\f': result = "\\f"
|
||||||
|
of '\e': result = "\\e"
|
||||||
|
of '\a': result = "\\a"
|
||||||
|
of '\\': result = "\\\\"
|
||||||
|
of 'a'..'z', 'A'..'Z', '0'..'9', '_': result = $c
|
||||||
|
elif c < ' ' or c >= '\128': result = '\\' & $ord(c)
|
||||||
|
elif c in reserved: result = '\\' & c
|
||||||
|
else: result = $c
|
||||||
|
|
||||||
|
proc singleQuoteEsc(c: Char): string = return "'" & esc(c, {'\''}) & "'"
|
||||||
|
|
||||||
|
proc singleQuoteEsc(str: string): string =
|
||||||
|
result = "'"
|
||||||
|
for c in items(str): add result, esc(c, {'\''})
|
||||||
|
add result, '\''
|
||||||
|
|
||||||
|
proc charSetEscAux(cc: set[char]): string =
|
||||||
|
const reserved = {'^', '-', ']'}
|
||||||
|
result = ""
|
||||||
|
var c1 = 0
|
||||||
|
while c1 <= 0xff:
|
||||||
|
if chr(c1) in cc:
|
||||||
|
var c2 = c1
|
||||||
|
while c2 < 0xff and chr(succ(c2)) in cc: inc(c2)
|
||||||
|
if c1 == c2:
|
||||||
|
add result, esc(chr(c1), reserved)
|
||||||
|
elif c2 == succ(c1):
|
||||||
|
add result, esc(chr(c1), reserved) & esc(chr(c2), reserved)
|
||||||
|
else:
|
||||||
|
add result, esc(chr(c1), reserved) & '-' & esc(chr(c2), reserved)
|
||||||
|
c1 = c2
|
||||||
|
inc(c1)
|
||||||
|
|
||||||
|
proc CharSetEsc(cc: set[char]): string =
|
||||||
|
if card(cc) >= 128+64:
|
||||||
|
result = "[^" & CharSetEscAux({'\1'..'\xFF'} - cc) & ']'
|
||||||
|
else:
|
||||||
|
result = '[' & CharSetEscAux(cc) & ']'
|
||||||
|
|
||||||
|
proc toStrAux(r: TPeg, res: var string) =
|
||||||
|
case r.kind
|
||||||
|
of pkEmpty: add(res, "()")
|
||||||
|
of pkAny: add(res, '.')
|
||||||
|
of pkAnyRune: add(res, '_')
|
||||||
|
of pkNewline: add(res, "\\n")
|
||||||
|
of pkTerminal: add(res, singleQuoteEsc(r.term))
|
||||||
|
of pkTerminalIgnoreCase:
|
||||||
|
add(res, 'i')
|
||||||
|
add(res, singleQuoteEsc(r.term))
|
||||||
|
of pkTerminalIgnoreStyle:
|
||||||
|
add(res, 'y')
|
||||||
|
add(res, singleQuoteEsc(r.term))
|
||||||
|
of pkChar: add(res, singleQuoteEsc(r.ch))
|
||||||
|
of pkCharChoice: add(res, charSetEsc(r.charChoice^))
|
||||||
|
of pkNonTerminal: add(res, r.nt.name)
|
||||||
|
of pkSequence:
|
||||||
|
add(res, '(')
|
||||||
|
toStrAux(r.sons[0], res)
|
||||||
|
for i in 1 .. high(r.sons):
|
||||||
|
add(res, ' ')
|
||||||
|
toStrAux(r.sons[i], res)
|
||||||
|
add(res, ')')
|
||||||
|
of pkOrderedChoice:
|
||||||
|
add(res, '(')
|
||||||
|
toStrAux(r.sons[0], res)
|
||||||
|
for i in 1 .. high(r.sons):
|
||||||
|
add(res, " / ")
|
||||||
|
toStrAux(r.sons[i], res)
|
||||||
|
add(res, ')')
|
||||||
|
of pkGreedyRep:
|
||||||
|
toStrAux(r.sons[0], res)
|
||||||
|
add(res, '*')
|
||||||
|
of pkGreedyRepChar:
|
||||||
|
add(res, singleQuoteEsc(r.ch))
|
||||||
|
add(res, '*')
|
||||||
|
of pkGreedyRepSet:
|
||||||
|
add(res, charSetEsc(r.charChoice^))
|
||||||
|
add(res, '*')
|
||||||
|
of pkGreedyAny:
|
||||||
|
add(res, ".*")
|
||||||
|
of pkOption:
|
||||||
|
toStrAux(r.sons[0], res)
|
||||||
|
add(res, '?')
|
||||||
|
of pkAndPredicate:
|
||||||
|
add(res, '&')
|
||||||
|
toStrAux(r.sons[0], res)
|
||||||
|
of pkNotPredicate:
|
||||||
|
add(res, '!')
|
||||||
|
toStrAux(r.sons[0], res)
|
||||||
|
of pkSearch:
|
||||||
|
add(res, '@')
|
||||||
|
toStrAux(r.sons[0], res)
|
||||||
|
of pkCapture:
|
||||||
|
add(res, '{')
|
||||||
|
toStrAux(r.sons[0], res)
|
||||||
|
add(res, '}')
|
||||||
|
of pkRule:
|
||||||
|
toStrAux(r.sons[0], res)
|
||||||
|
add(res, " <- ")
|
||||||
|
toStrAux(r.sons[1], res)
|
||||||
|
of pkList:
|
||||||
|
for i in 0 .. high(r.sons):
|
||||||
|
toStrAux(r.sons[i], res)
|
||||||
|
add(res, "\n")
|
||||||
|
|
||||||
|
proc `$` *(r: TPeg): string =
|
||||||
|
## converts a PEG to its string representation
|
||||||
|
result = ""
|
||||||
|
toStrAux(r, result)
|
||||||
|
|
||||||
# --------------------- core engine -------------------------------------------
|
# --------------------- core engine -------------------------------------------
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -370,6 +507,17 @@ proc m(s: string, p: TPeg, start: int, c: var TMatchClosure): int =
|
||||||
result = m(s, p.sons[i], start, c)
|
result = m(s, p.sons[i], start, c)
|
||||||
if result >= 0: break
|
if result >= 0: break
|
||||||
c.ml = oldMl
|
c.ml = oldMl
|
||||||
|
of pkSearch:
|
||||||
|
var oldMl = c.ml
|
||||||
|
result = 0
|
||||||
|
while start+result < s.len:
|
||||||
|
var x = m(s, p.sons[0], start+result, c)
|
||||||
|
if x >= 0:
|
||||||
|
inc(result, x)
|
||||||
|
return
|
||||||
|
inc(result)
|
||||||
|
result = -1
|
||||||
|
c.ml = oldMl
|
||||||
of pkGreedyRep:
|
of pkGreedyRep:
|
||||||
result = 0
|
result = 0
|
||||||
while true:
|
while true:
|
||||||
|
|
@ -607,123 +755,6 @@ proc split*(s: string, sep: TPeg): seq[string] {.noSideEffect.} =
|
||||||
## Splits the string `s` into substrings.
|
## Splits the string `s` into substrings.
|
||||||
accumulateResult(split(s, sep))
|
accumulateResult(split(s, sep))
|
||||||
|
|
||||||
# ------------------------- debugging -----------------------------------------
|
|
||||||
|
|
||||||
proc esc(c: char, reserved = {'\0'..'\255'}): string =
|
|
||||||
case c
|
|
||||||
of '\b': result = "\\b"
|
|
||||||
of '\t': result = "\\t"
|
|
||||||
of '\c': result = "\\c"
|
|
||||||
of '\L': result = "\\l"
|
|
||||||
of '\v': result = "\\v"
|
|
||||||
of '\f': result = "\\f"
|
|
||||||
of '\e': result = "\\e"
|
|
||||||
of '\a': result = "\\a"
|
|
||||||
of '\\': result = "\\\\"
|
|
||||||
of 'a'..'z', 'A'..'Z', '0'..'9', '_': result = $c
|
|
||||||
elif c < ' ' or c >= '\128': result = '\\' & $ord(c)
|
|
||||||
elif c in reserved: result = '\\' & c
|
|
||||||
else: result = $c
|
|
||||||
|
|
||||||
proc singleQuoteEsc(c: Char): string = return "'" & esc(c, {'\''}) & "'"
|
|
||||||
|
|
||||||
proc singleQuoteEsc(str: string): string =
|
|
||||||
result = "'"
|
|
||||||
for c in items(str): add result, esc(c, {'\''})
|
|
||||||
add result, '\''
|
|
||||||
|
|
||||||
proc charSetEscAux(cc: set[char]): string =
|
|
||||||
const reserved = {'^', '-', ']'}
|
|
||||||
result = ""
|
|
||||||
var c1 = 0
|
|
||||||
while c1 <= 0xff:
|
|
||||||
if chr(c1) in cc:
|
|
||||||
var c2 = c1
|
|
||||||
while c2 < 0xff and chr(succ(c2)) in cc: inc(c2)
|
|
||||||
if c1 == c2:
|
|
||||||
add result, esc(chr(c1), reserved)
|
|
||||||
elif c2 == succ(c1):
|
|
||||||
add result, esc(chr(c1), reserved) & esc(chr(c2), reserved)
|
|
||||||
else:
|
|
||||||
add result, esc(chr(c1), reserved) & '-' & esc(chr(c2), reserved)
|
|
||||||
c1 = c2
|
|
||||||
inc(c1)
|
|
||||||
|
|
||||||
proc CharSetEsc(cc: set[char]): string =
|
|
||||||
if card(cc) >= 128+64:
|
|
||||||
result = "[^" & CharSetEscAux({'\1'..'\xFF'} - cc) & ']'
|
|
||||||
else:
|
|
||||||
result = '[' & CharSetEscAux(cc) & ']'
|
|
||||||
|
|
||||||
proc toStrAux(r: TPeg, res: var string) =
|
|
||||||
case r.kind
|
|
||||||
of pkEmpty: add(res, "()")
|
|
||||||
of pkAny: add(res, '.')
|
|
||||||
of pkAnyRune: add(res, '_')
|
|
||||||
of pkNewline: add(res, "\\n")
|
|
||||||
of pkTerminal: add(res, singleQuoteEsc(r.term))
|
|
||||||
of pkTerminalIgnoreCase:
|
|
||||||
add(res, 'i')
|
|
||||||
add(res, singleQuoteEsc(r.term))
|
|
||||||
of pkTerminalIgnoreStyle:
|
|
||||||
add(res, 'y')
|
|
||||||
add(res, singleQuoteEsc(r.term))
|
|
||||||
of pkChar: add(res, singleQuoteEsc(r.ch))
|
|
||||||
of pkCharChoice: add(res, charSetEsc(r.charChoice^))
|
|
||||||
of pkNonTerminal: add(res, r.nt.name)
|
|
||||||
of pkSequence:
|
|
||||||
add(res, '(')
|
|
||||||
toStrAux(r.sons[0], res)
|
|
||||||
for i in 1 .. high(r.sons):
|
|
||||||
add(res, ' ')
|
|
||||||
toStrAux(r.sons[i], res)
|
|
||||||
add(res, ')')
|
|
||||||
of pkOrderedChoice:
|
|
||||||
add(res, '(')
|
|
||||||
toStrAux(r.sons[0], res)
|
|
||||||
for i in 1 .. high(r.sons):
|
|
||||||
add(res, " / ")
|
|
||||||
toStrAux(r.sons[i], res)
|
|
||||||
add(res, ')')
|
|
||||||
of pkGreedyRep:
|
|
||||||
toStrAux(r.sons[0], res)
|
|
||||||
add(res, '*')
|
|
||||||
of pkGreedyRepChar:
|
|
||||||
add(res, singleQuoteEsc(r.ch))
|
|
||||||
add(res, '*')
|
|
||||||
of pkGreedyRepSet:
|
|
||||||
add(res, charSetEsc(r.charChoice^))
|
|
||||||
add(res, '*')
|
|
||||||
of pkGreedyAny:
|
|
||||||
add(res, ".*")
|
|
||||||
of pkOption:
|
|
||||||
toStrAux(r.sons[0], res)
|
|
||||||
add(res, '?')
|
|
||||||
of pkAndPredicate:
|
|
||||||
add(res, '&')
|
|
||||||
toStrAux(r.sons[0], res)
|
|
||||||
of pkNotPredicate:
|
|
||||||
add(res, '!')
|
|
||||||
toStrAux(r.sons[0], res)
|
|
||||||
of pkCapture:
|
|
||||||
add(res, '{')
|
|
||||||
toStrAux(r.sons[0], res)
|
|
||||||
add(res, '}')
|
|
||||||
of pkRule:
|
|
||||||
toStrAux(r.sons[0], res)
|
|
||||||
add(res, " <- ")
|
|
||||||
toStrAux(r.sons[1], res)
|
|
||||||
of pkList:
|
|
||||||
for i in 0 .. high(r.sons):
|
|
||||||
toStrAux(r.sons[i], res)
|
|
||||||
add(res, "\n")
|
|
||||||
|
|
||||||
proc `$` *(r: TPeg): string =
|
|
||||||
## converts a PEG to its string representation
|
|
||||||
result = ""
|
|
||||||
toStrAux(r, result)
|
|
||||||
|
|
||||||
|
|
||||||
# ------------------- scanner -------------------------------------------------
|
# ------------------- scanner -------------------------------------------------
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -751,6 +782,7 @@ type
|
||||||
tkAmp, ## '&'
|
tkAmp, ## '&'
|
||||||
tkNot, ## '!'
|
tkNot, ## '!'
|
||||||
tkOption, ## '?'
|
tkOption, ## '?'
|
||||||
|
tkAt, ## '@'
|
||||||
tkBuiltin, ## \identifier
|
tkBuiltin, ## \identifier
|
||||||
tkEscaped ## \\
|
tkEscaped ## \\
|
||||||
|
|
||||||
|
|
@ -772,7 +804,7 @@ const
|
||||||
tokKindToStr: array[TTokKind, string] = [
|
tokKindToStr: array[TTokKind, string] = [
|
||||||
"invalid", "[EOF]", ".", "_", "identifier", "string literal",
|
"invalid", "[EOF]", ".", "_", "identifier", "string literal",
|
||||||
"character set", "(", ")", "{", "}", "<-", "/", "*", "+", "&", "!", "?",
|
"character set", "(", ")", "{", "}", "<-", "/", "*", "+", "&", "!", "?",
|
||||||
"built-in", "escaped"
|
"@", "built-in", "escaped"
|
||||||
]
|
]
|
||||||
|
|
||||||
proc HandleCR(L: var TPegLexer, pos: int): int =
|
proc HandleCR(L: var TPegLexer, pos: int): int =
|
||||||
|
|
@ -1063,6 +1095,10 @@ proc getTok(c: var TPegLexer, tok: var TToken) =
|
||||||
tok.kind = tkAmp
|
tok.kind = tkAmp
|
||||||
inc(c.bufpos)
|
inc(c.bufpos)
|
||||||
add(tok.literal, '!')
|
add(tok.literal, '!')
|
||||||
|
of '@':
|
||||||
|
tok.kind = tkAt
|
||||||
|
inc(c.bufpos)
|
||||||
|
add(tok.literal, '@')
|
||||||
else:
|
else:
|
||||||
add(tok.literal, c.buf[c.bufpos])
|
add(tok.literal, c.buf[c.bufpos])
|
||||||
inc(c.bufpos)
|
inc(c.bufpos)
|
||||||
|
|
@ -1118,6 +1154,9 @@ proc primary(p: var TPegParser): TPeg =
|
||||||
of tkNot:
|
of tkNot:
|
||||||
getTok(p)
|
getTok(p)
|
||||||
return !primary(p)
|
return !primary(p)
|
||||||
|
of tkAt:
|
||||||
|
getTok(p)
|
||||||
|
return @primary(p)
|
||||||
else: nil
|
else: nil
|
||||||
case p.tok.kind
|
case p.tok.kind
|
||||||
of tkIdentifier:
|
of tkIdentifier:
|
||||||
|
|
@ -1187,7 +1226,7 @@ proc seqExpr(p: var TPegParser): TPeg =
|
||||||
result = primary(p)
|
result = primary(p)
|
||||||
while true:
|
while true:
|
||||||
case p.tok.kind
|
case p.tok.kind
|
||||||
of tkAmp, tkNot, tkStringLit, tkCharset, tkParLe, tkCurlyLe,
|
of tkAmp, tkNot, tkAt, tkStringLit, tkCharset, tkParLe, tkCurlyLe,
|
||||||
tkAny, tkAnyRune, tkBuiltin, tkEscaped:
|
tkAny, tkAnyRune, tkBuiltin, tkEscaped:
|
||||||
result = sequence(result, primary(p))
|
result = sequence(result, primary(p))
|
||||||
of tkIdentifier:
|
of tkIdentifier:
|
||||||
|
|
@ -1261,6 +1300,7 @@ proc peg*(pattern: string): TPeg =
|
||||||
result = parsePeg(pattern, "pattern")
|
result = parsePeg(pattern, "pattern")
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
|
assert match("(a b c)", peg"'(' @ ')'")
|
||||||
assert match("W_HI_Le", peg"\y 'while'")
|
assert match("W_HI_Le", peg"\y 'while'")
|
||||||
assert(not match("W_HI_L", peg"\y 'while'"))
|
assert(not match("W_HI_L", peg"\y 'while'"))
|
||||||
assert(not match("W_HI_Le", peg"\y v'while'"))
|
assert(not match("W_HI_Le", peg"\y v'while'"))
|
||||||
|
|
@ -1315,6 +1355,11 @@ when isMainModule:
|
||||||
"""
|
"""
|
||||||
assert($g2 == "((A B) / (C D))")
|
assert($g2 == "((A B) / (C D))")
|
||||||
assert match("cccccdddddd", g2)
|
assert match("cccccdddddd", g2)
|
||||||
echo "var1=key; var2=key2".replace(peg"{\ident}'='{\ident}", "$1<-$2$2")
|
assert("var1=key; var2=key2".replace(peg"{\ident}'='{\ident}", "$1<-$2$2") ==
|
||||||
|
"var1<-keykey; var2<-key2key2")
|
||||||
assert "var1=key; var2=key2".endsWith(peg"{\ident}'='{\ident}")
|
assert "var1=key; var2=key2".endsWith(peg"{\ident}'='{\ident}")
|
||||||
|
|
||||||
|
if "aaaaaa" =~ peg"'aa' !. / ({'a'})+":
|
||||||
|
assert matches[0] == "a"
|
||||||
|
else:
|
||||||
|
assert false
|
||||||
|
|
|
||||||
|
|
@ -44,15 +44,13 @@ proc runeLenAt*(s: string, i: int): int =
|
||||||
template fastRuneAt*(s: string, i: int, result: expr, doInc = true) =
|
template fastRuneAt*(s: string, i: int, result: expr, doInc = true) =
|
||||||
## Returns the unicode character ``s[i]`` in `result`. If ``doInc == true``
|
## Returns the unicode character ``s[i]`` in `result`. If ``doInc == true``
|
||||||
## `i` is incremented by the number of bytes that have been processed.
|
## `i` is incremented by the number of bytes that have been processed.
|
||||||
when not defined(ones):
|
|
||||||
template ones(n: expr): expr = ((1 shl n)-1)
|
|
||||||
|
|
||||||
if ord(s[i]) <=% 127:
|
if ord(s[i]) <=% 127:
|
||||||
result = TRune(ord(s[i]))
|
result = TRune(ord(s[i]))
|
||||||
when doInc: inc(i)
|
when doInc: inc(i)
|
||||||
elif ord(s[i]) shr 5 == 0b110:
|
elif ord(s[i]) shr 5 == 0b110:
|
||||||
assert(ord(s[i+1]) shr 6 == 0b10)
|
assert(ord(s[i+1]) shr 6 == 0b10)
|
||||||
result = TRune((ord(s[i]) and ones(5)) shl 6 or (ord(s[i+1]) and ones(6)))
|
result = TRune((ord(s[i]) and (bind ones(5))) shl 6 or
|
||||||
|
(ord(s[i+1]) and ones(6)))
|
||||||
when doInc: inc(i, 2)
|
when doInc: inc(i, 2)
|
||||||
elif ord(s[i]) shr 4 == 0b1110:
|
elif ord(s[i]) shr 4 == 0b1110:
|
||||||
assert(ord(s[i+1]) shr 6 == 0b10)
|
assert(ord(s[i+1]) shr 6 == 0b10)
|
||||||
|
|
|
||||||
139
nim/llvmdata.pas
Executable file
139
nim/llvmdata.pas
Executable file
|
|
@ -0,0 +1,139 @@
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// The Nimrod Compiler
|
||||||
|
// (c) Copyright 2009 Andreas Rumpf
|
||||||
|
//
|
||||||
|
// See the file "copying.txt", included in this
|
||||||
|
// distribution, for details about the copyright.
|
||||||
|
//
|
||||||
|
unit llvmdata;
|
||||||
|
|
||||||
|
// this module implements data structures for emitting LLVM.
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
{$include 'config.inc'}
|
||||||
|
|
||||||
|
uses
|
||||||
|
nsystem, ast, astalgo, idents, lists, passes;
|
||||||
|
|
||||||
|
type
|
||||||
|
VTypeKind = (
|
||||||
|
VoidTyID, ///< 0: type with no size
|
||||||
|
FloatTyID, ///< 1: 32 bit floating point type
|
||||||
|
DoubleTyID, ///< 2: 64 bit floating point type
|
||||||
|
X86_FP80TyID, ///< 3: 80 bit floating point type (X87)
|
||||||
|
FP128TyID, ///< 4: 128 bit floating point type (112-bit mantissa)
|
||||||
|
PPC_FP128TyID, ///< 5: 128 bit floating point type (two 64-bits)
|
||||||
|
LabelTyID, ///< 6: Labels
|
||||||
|
MetadataTyID, ///< 7: Metadata
|
||||||
|
|
||||||
|
// Derived types... see DerivedTypes.h file...
|
||||||
|
// Make sure FirstDerivedTyID stays up to date!!!
|
||||||
|
IntegerTyID, ///< 8: Arbitrary bit width integers
|
||||||
|
FunctionTyID, ///< 9: Functions
|
||||||
|
StructTyID, ///< 10: Structures
|
||||||
|
ArrayTyID, ///< 11: Arrays
|
||||||
|
PointerTyID, ///< 12: Pointers
|
||||||
|
OpaqueTyID, ///< 13: Opaque: type with unknown structure
|
||||||
|
VectorTyID, ///< 14: SIMD 'packed' format, or other vector type
|
||||||
|
);
|
||||||
|
VType = ^VTypeDesc;
|
||||||
|
VTypeSeq = array of VType;
|
||||||
|
VTypeDesc = object(TIdObj)
|
||||||
|
k: VTypeKind;
|
||||||
|
s: VTypeSeq;
|
||||||
|
arrayLen: int;
|
||||||
|
name: string;
|
||||||
|
end;
|
||||||
|
|
||||||
|
VInstrKind = (
|
||||||
|
iNone,
|
||||||
|
iAdd,
|
||||||
|
iSub,
|
||||||
|
iMul,
|
||||||
|
iDiv,
|
||||||
|
iMod,
|
||||||
|
|
||||||
|
);
|
||||||
|
VLocalVar = record
|
||||||
|
|
||||||
|
|
||||||
|
end;
|
||||||
|
VInstr = record
|
||||||
|
k: VInstrKind;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
/// This represents a single basic block in LLVM. A basic block is simply a
|
||||||
|
/// container of instructions that execute sequentially. Basic blocks are Values
|
||||||
|
/// because they are referenced by instructions such as branches and switch
|
||||||
|
/// tables. The type of a BasicBlock is "Type::LabelTy" because the basic block
|
||||||
|
/// represents a label to which a branch can jump.
|
||||||
|
///
|
||||||
|
VBlock = ^VBlockDesc;
|
||||||
|
VBlockDesc = record // LLVM basic block
|
||||||
|
// list of instructions
|
||||||
|
end;
|
||||||
|
|
||||||
|
VLinkage = (
|
||||||
|
ExternalLinkage, // Externally visible function
|
||||||
|
LinkOnceLinkage, // Keep one copy of function when linking (inline)
|
||||||
|
WeakLinkage, // Keep one copy of function when linking (weak)
|
||||||
|
AppendingLinkage, // Special purpose, only applies to global arrays
|
||||||
|
InternalLinkage, // Rename collisions when linking (static functions)
|
||||||
|
DLLImportLinkage, // Function to be imported from DLL
|
||||||
|
DLLExportLinkage, // Function to be accessible from DLL
|
||||||
|
ExternalWeakLinkage, // ExternalWeak linkage description
|
||||||
|
GhostLinkage // Stand-in functions for streaming fns from bitcode
|
||||||
|
);
|
||||||
|
VVisibility = (
|
||||||
|
DefaultVisibility, // The GV is visible
|
||||||
|
HiddenVisibility, // The GV is hidden
|
||||||
|
ProtectedVisibility // The GV is protected
|
||||||
|
);
|
||||||
|
TLLVMCallConv = (
|
||||||
|
CCallConv = 0,
|
||||||
|
FastCallConv = 8,
|
||||||
|
ColdCallConv = 9,
|
||||||
|
X86StdcallCallConv = 64,
|
||||||
|
X86FastcallCallConv = 65
|
||||||
|
);
|
||||||
|
|
||||||
|
VProc = ^VProcDesc;
|
||||||
|
VProcDesc = record
|
||||||
|
b: VBlock;
|
||||||
|
name: string;
|
||||||
|
sym: PSym; // proc that is generated
|
||||||
|
linkage: VLinkage;
|
||||||
|
vis: VVisibility;
|
||||||
|
callConv: VCallConv;
|
||||||
|
next: VProc;
|
||||||
|
end;
|
||||||
|
VModule = ^VModuleDesc;
|
||||||
|
VModuleDesc = object(TPassContext) // represents a C source file
|
||||||
|
sym: PSym;
|
||||||
|
filename: string;
|
||||||
|
typeCache: TIdTable; // cache the generated types
|
||||||
|
forwTypeCache: TIdTable; // cache for forward declarations of types
|
||||||
|
declaredThings: TIntSet; // things we have declared in this file
|
||||||
|
declaredProtos: TIntSet; // prototypes we have declared in this file
|
||||||
|
headerFiles: TLinkedList; // needed headers to include
|
||||||
|
typeInfoMarker: TIntSet; // needed for generating type information
|
||||||
|
initProc: VProc; // code for init procedure
|
||||||
|
typeStack: TTypeSeq; // used for type generation
|
||||||
|
dataCache: TNodeTable;
|
||||||
|
forwardedProcs: TSymSeq; // keep forwarded procs here
|
||||||
|
typeNodes, nimTypes: int;// used for type info generation
|
||||||
|
typeNodesName, nimTypesName: PRope; // used for type info generation
|
||||||
|
labels: natural; // for generating unique module-scope names
|
||||||
|
next: VModule; // to stack modules
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
||||||
120
nim/pbraces.pas
120
nim/pbraces.pas
|
|
@ -146,8 +146,7 @@ begin
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure qualifiedIdentListAux(var p: TParser; endTok: TTokType;
|
procedure qualifiedIdentListAux(var p: TParser; endTok: TTokType; result: PNode);
|
||||||
result: PNode);
|
|
||||||
var
|
var
|
||||||
a: PNode;
|
a: PNode;
|
||||||
begin
|
begin
|
||||||
|
|
@ -216,16 +215,6 @@ begin
|
||||||
eat(p, tkParRi);
|
eat(p, tkParRi);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure setBaseFlags(n: PNode; base: TNumericalBase);
|
|
||||||
begin
|
|
||||||
case base of
|
|
||||||
base10: begin end;
|
|
||||||
base2: include(n.flags, nfBase2);
|
|
||||||
base8: include(n.flags, nfBase8);
|
|
||||||
base16: include(n.flags, nfBase16);
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
|
|
||||||
function identOrLiteral(var p: TParser): PNode;
|
function identOrLiteral(var p: TParser): PNode;
|
||||||
begin
|
begin
|
||||||
case p.tok.tokType of
|
case p.tok.tokType of
|
||||||
|
|
@ -729,12 +718,12 @@ begin
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function parseImportStmt(var p: TParser): PNode;
|
function parseImportOrIncludeStmt(var p: TParser; kind: TNodeKind): PNode;
|
||||||
var
|
var
|
||||||
a: PNode;
|
a: PNode;
|
||||||
begin
|
begin
|
||||||
result := newNodeP(nkImportStmt, p);
|
result := newNodeP(kind, p);
|
||||||
getTok(p); // skip `import`
|
getTok(p); // skip `import` or `include`
|
||||||
optInd(p, result);
|
optInd(p, result);
|
||||||
while true do begin
|
while true do begin
|
||||||
case p.tok.tokType of
|
case p.tok.tokType of
|
||||||
|
|
@ -764,41 +753,6 @@ begin
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function parseIncludeStmt(var p: TParser): PNode;
|
|
||||||
var
|
|
||||||
a: PNode;
|
|
||||||
begin
|
|
||||||
result := newNodeP(nkIncludeStmt, p);
|
|
||||||
getTok(p); // skip `include`
|
|
||||||
optInd(p, result);
|
|
||||||
while true do begin
|
|
||||||
case p.tok.tokType of
|
|
||||||
tkEof, tkSad, tkDed: break;
|
|
||||||
tkSymbol, tkAccent: a := parseSymbol(p);
|
|
||||||
tkRStrLit: begin
|
|
||||||
a := newStrNodeP(nkRStrLit, p.tok.literal, p);
|
|
||||||
getTok(p)
|
|
||||||
end;
|
|
||||||
tkStrLit: begin
|
|
||||||
a := newStrNodeP(nkStrLit, p.tok.literal, p);
|
|
||||||
getTok(p);
|
|
||||||
end;
|
|
||||||
tkTripleStrLit: begin
|
|
||||||
a := newStrNodeP(nkTripleStrLit, p.tok.literal, p);
|
|
||||||
getTok(p)
|
|
||||||
end;
|
|
||||||
else begin
|
|
||||||
parMessage(p, errIdentifierExpected, tokToStr(p.tok));
|
|
||||||
break
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
addSon(result, a);
|
|
||||||
if p.tok.tokType <> tkComma then break;
|
|
||||||
getTok(p);
|
|
||||||
optInd(p, a)
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function parseFromStmt(var p: TParser): PNode;
|
function parseFromStmt(var p: TParser): PNode;
|
||||||
var
|
var
|
||||||
a: PNode;
|
a: PNode;
|
||||||
|
|
@ -1150,6 +1104,24 @@ begin
|
||||||
indAndComment(p, result); // XXX: special extension!
|
indAndComment(p, result); // XXX: special extension!
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function parseConstSection(var p: TParser): PNode;
|
||||||
|
begin
|
||||||
|
result := newNodeP(nkConstSection, p);
|
||||||
|
getTok(p);
|
||||||
|
skipComment(p, result);
|
||||||
|
if p.tok.tokType = tkCurlyLe then begin
|
||||||
|
getTok(p);
|
||||||
|
skipComment(p, result);
|
||||||
|
while (p.tok.tokType <> tkCurlyRi) and (p.tok.tokType <> tkEof) do begin
|
||||||
|
addSon(result, parseConstant(p))
|
||||||
|
end;
|
||||||
|
eat(p, tkCurlyRi);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
addSon(result, parseConstant(p));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function parseEnum(var p: TParser): PNode;
|
function parseEnum(var p: TParser): PNode;
|
||||||
var
|
var
|
||||||
a, b: PNode;
|
a, b: PNode;
|
||||||
|
|
@ -1379,9 +1351,9 @@ begin
|
||||||
tkBreak: result := parseBreakOrContinue(p, nkBreakStmt);
|
tkBreak: result := parseBreakOrContinue(p, nkBreakStmt);
|
||||||
tkContinue: result := parseBreakOrContinue(p, nkContinueStmt);
|
tkContinue: result := parseBreakOrContinue(p, nkContinueStmt);
|
||||||
tkCurlyDotLe: result := parsePragma(p);
|
tkCurlyDotLe: result := parsePragma(p);
|
||||||
tkImport: result := parseImportStmt(p);
|
tkImport: result := parseImportOrIncludeStmt(p, nkImportStmt);
|
||||||
tkFrom: result := parseFromStmt(p);
|
tkFrom: result := parseFromStmt(p);
|
||||||
tkInclude: result := parseIncludeStmt(p);
|
tkInclude: result := parseImportOrIncludeStmt(p, nkIncludeStmt);
|
||||||
tkComment: result := newCommentStmt(p);
|
tkComment: result := newCommentStmt(p);
|
||||||
else begin
|
else begin
|
||||||
if isExprStart(p) then
|
if isExprStart(p) then
|
||||||
|
|
@ -1394,6 +1366,24 @@ begin
|
||||||
skipComment(p, result);
|
skipComment(p, result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function parseType(var p: TParser): PNode;
|
||||||
|
begin
|
||||||
|
result := newNodeP(nkTypeSection, p);
|
||||||
|
while true do begin
|
||||||
|
case p.tok.tokType of
|
||||||
|
tkComment: skipComment(p, result);
|
||||||
|
tkType: begin
|
||||||
|
// type alias:
|
||||||
|
|
||||||
|
end;
|
||||||
|
tkEnum:
|
||||||
|
tkObject:
|
||||||
|
tkTuple:
|
||||||
|
else break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
function complexOrSimpleStmt(var p: TParser): PNode;
|
function complexOrSimpleStmt(var p: TParser): PNode;
|
||||||
begin
|
begin
|
||||||
case p.tok.tokType of
|
case p.tok.tokType of
|
||||||
|
|
@ -1410,8 +1400,9 @@ begin
|
||||||
tkMacro: result := parseRoutine(p, nkMacroDef);
|
tkMacro: result := parseRoutine(p, nkMacroDef);
|
||||||
tkTemplate: result := parseRoutine(p, nkTemplateDef);
|
tkTemplate: result := parseRoutine(p, nkTemplateDef);
|
||||||
tkConverter: result := parseRoutine(p, nkConverterDef);
|
tkConverter: result := parseRoutine(p, nkConverterDef);
|
||||||
tkType: result := parseSection(p, nkTypeSection, parseTypeDef);
|
tkType, tkEnum, tkObject, tkTuple:
|
||||||
tkConst: result := parseSection(p, nkConstSection, parseConstant);
|
result := parseTypeAlias(p, nkTypeSection, parseTypeDef);
|
||||||
|
tkConst: result := parseConstSection(p);
|
||||||
tkWhen: result := parseIfOrWhen(p, nkWhenStmt);
|
tkWhen: result := parseIfOrWhen(p, nkWhenStmt);
|
||||||
tkVar: result := parseSection(p, nkVarSection, parseVariable);
|
tkVar: result := parseSection(p, nkVarSection, parseVariable);
|
||||||
else result := simpleStmt(p);
|
else result := simpleStmt(p);
|
||||||
|
|
@ -1422,15 +1413,13 @@ function parseStmt(var p: TParser): PNode;
|
||||||
var
|
var
|
||||||
a: PNode;
|
a: PNode;
|
||||||
begin
|
begin
|
||||||
if p.tok.tokType = tkInd then begin
|
if p.tok.tokType = tkCurlyLe then begin
|
||||||
result := newNodeP(nkStmtList, p);
|
result := newNodeP(nkStmtList, p);
|
||||||
pushInd(p.lex^, p.tok.indent);
|
|
||||||
getTok(p);
|
getTok(p);
|
||||||
while true do begin
|
while true do begin
|
||||||
case p.tok.tokType of
|
case p.tok.tokType of
|
||||||
tkSad: getTok(p);
|
tkSad, tkInd, tkDed: getTok(p);
|
||||||
tkEof: break;
|
tkEof, tkCurlyRi: break;
|
||||||
tkDed: begin getTok(p); break end;
|
|
||||||
else begin
|
else begin
|
||||||
a := complexOrSimpleStmt(p);
|
a := complexOrSimpleStmt(p);
|
||||||
if a = nil then break;
|
if a = nil then break;
|
||||||
|
|
@ -1438,7 +1427,7 @@ begin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
popInd(p.lex^);
|
eat(p, tkCurlyRi);
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
// the case statement is only needed for better error messages:
|
// the case statement is only needed for better error messages:
|
||||||
|
|
@ -1451,7 +1440,7 @@ begin
|
||||||
else begin
|
else begin
|
||||||
result := simpleStmt(p);
|
result := simpleStmt(p);
|
||||||
if result = nil then parMessage(p, errExprExpected, tokToStr(p.tok));
|
if result = nil then parMessage(p, errExprExpected, tokToStr(p.tok));
|
||||||
if p.tok.tokType = tkSad then getTok(p);
|
if p.tok.tokType in [tkInd, tkDed, tkSad] then getTok(p);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -1464,8 +1453,7 @@ begin
|
||||||
result := newNodeP(nkStmtList, p);
|
result := newNodeP(nkStmtList, p);
|
||||||
while true do begin
|
while true do begin
|
||||||
case p.tok.tokType of
|
case p.tok.tokType of
|
||||||
tkSad: getTok(p);
|
tkDed, tkInd, tkSad: getTok(p);
|
||||||
tkDed, tkInd: parMessage(p, errInvalidIndentation);
|
|
||||||
tkEof: break;
|
tkEof: break;
|
||||||
else begin
|
else begin
|
||||||
a := complexOrSimpleStmt(p);
|
a := complexOrSimpleStmt(p);
|
||||||
|
|
@ -1481,11 +1469,7 @@ begin
|
||||||
result := nil;
|
result := nil;
|
||||||
while true do begin
|
while true do begin
|
||||||
case p.tok.tokType of
|
case p.tok.tokType of
|
||||||
tkSad: getTok(p);
|
tkDed, tkInd, tkSad: getTok(p);
|
||||||
tkDed, tkInd: begin
|
|
||||||
parMessage(p, errInvalidIndentation);
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
tkEof: break;
|
tkEof: break;
|
||||||
else begin
|
else begin
|
||||||
result := complexOrSimpleStmt(p);
|
result := complexOrSimpleStmt(p);
|
||||||
|
|
|
||||||
36
nim/pendx.pas
Executable file
36
nim/pendx.pas
Executable file
|
|
@ -0,0 +1,36 @@
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// The Nimrod Compiler
|
||||||
|
// (c) Copyright 2009 Andreas Rumpf
|
||||||
|
//
|
||||||
|
// See the file "copying.txt", included in this
|
||||||
|
// distribution, for details about the copyright.
|
||||||
|
//
|
||||||
|
unit pendx;
|
||||||
|
|
||||||
|
{$include config.inc}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
nsystem, llstream, scanner, idents, strutils, ast, msgs, pnimsyn;
|
||||||
|
|
||||||
|
function ParseAll(var p: TParser): PNode;
|
||||||
|
|
||||||
|
function parseTopLevelStmt(var p: TParser): PNode;
|
||||||
|
// implements an iterator. Returns the next top-level statement or nil if end
|
||||||
|
// of stream.
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
function ParseAll(var p: TParser): PNode;
|
||||||
|
begin
|
||||||
|
result := nil
|
||||||
|
end;
|
||||||
|
|
||||||
|
function parseTopLevelStmt(var p: TParser): PNode;
|
||||||
|
begin
|
||||||
|
result := nil
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
@ -72,6 +72,7 @@ procedure optSad(var p: TParser);
|
||||||
procedure optInd(var p: TParser; n: PNode);
|
procedure optInd(var p: TParser; n: PNode);
|
||||||
procedure indAndComment(var p: TParser; n: PNode);
|
procedure indAndComment(var p: TParser; n: PNode);
|
||||||
|
|
||||||
|
procedure setBaseFlags(n: PNode; base: TNumericalBase);
|
||||||
|
|
||||||
function parseSymbol(var p: TParser): PNode;
|
function parseSymbol(var p: TParser): PNode;
|
||||||
function accExpr(var p: TParser): PNode;
|
function accExpr(var p: TParser): PNode;
|
||||||
|
|
@ -1069,12 +1070,12 @@ begin
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function parseImportStmt(var p: TParser): PNode;
|
function parseImportOrIncludeStmt(var p: TParser; kind: TNodeKind): PNode;
|
||||||
var
|
var
|
||||||
a: PNode;
|
a: PNode;
|
||||||
begin
|
begin
|
||||||
result := newNodeP(nkImportStmt, p);
|
result := newNodeP(kind, p);
|
||||||
getTok(p); // skip `import`
|
getTok(p); // skip `import` or `include`
|
||||||
optInd(p, result);
|
optInd(p, result);
|
||||||
while true do begin
|
while true do begin
|
||||||
case p.tok.tokType of
|
case p.tok.tokType of
|
||||||
|
|
@ -1104,42 +1105,6 @@ begin
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function parseIncludeStmt(var p: TParser): PNode;
|
|
||||||
var
|
|
||||||
a: PNode;
|
|
||||||
begin
|
|
||||||
result := newNodeP(nkIncludeStmt, p);
|
|
||||||
getTok(p); // skip `include`
|
|
||||||
optInd(p, result);
|
|
||||||
while true do begin
|
|
||||||
case p.tok.tokType of
|
|
||||||
tkEof, tkSad, tkDed: break;
|
|
||||||
tkSymbol, tkAccent: a := parseSymbol(p);
|
|
||||||
tkRStrLit: begin
|
|
||||||
a := newStrNodeP(nkRStrLit, p.tok.literal, p);
|
|
||||||
getTok(p)
|
|
||||||
end;
|
|
||||||
tkStrLit: begin
|
|
||||||
a := newStrNodeP(nkStrLit, p.tok.literal, p);
|
|
||||||
getTok(p);
|
|
||||||
end;
|
|
||||||
tkTripleStrLit: begin
|
|
||||||
a := newStrNodeP(nkTripleStrLit, p.tok.literal, p);
|
|
||||||
getTok(p)
|
|
||||||
end;
|
|
||||||
else begin
|
|
||||||
parMessage(p, errIdentifierExpected, tokToStr(p.tok));
|
|
||||||
break
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
addSon(result, a);
|
|
||||||
//optInd(p, a);
|
|
||||||
if p.tok.tokType <> tkComma then break;
|
|
||||||
getTok(p);
|
|
||||||
optInd(p, a)
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function parseFromStmt(var p: TParser): PNode;
|
function parseFromStmt(var p: TParser): PNode;
|
||||||
var
|
var
|
||||||
a: PNode;
|
a: PNode;
|
||||||
|
|
@ -1717,9 +1682,9 @@ begin
|
||||||
tkBreak: result := parseBreakOrContinue(p, nkBreakStmt);
|
tkBreak: result := parseBreakOrContinue(p, nkBreakStmt);
|
||||||
tkContinue: result := parseBreakOrContinue(p, nkContinueStmt);
|
tkContinue: result := parseBreakOrContinue(p, nkContinueStmt);
|
||||||
tkCurlyDotLe: result := parsePragma(p);
|
tkCurlyDotLe: result := parsePragma(p);
|
||||||
tkImport: result := parseImportStmt(p);
|
tkImport: result := parseImportOrIncludeStmt(p, nkImportStmt);
|
||||||
tkFrom: result := parseFromStmt(p);
|
tkFrom: result := parseFromStmt(p);
|
||||||
tkInclude: result := parseIncludeStmt(p);
|
tkInclude: result := parseImportOrIncludeStmt(p, nkIncludeStmt);
|
||||||
tkComment: result := newCommentStmt(p);
|
tkComment: result := newCommentStmt(p);
|
||||||
else begin
|
else begin
|
||||||
if isExprStart(p) then
|
if isExprStart(p) then
|
||||||
|
|
|
||||||
287
nim/semgnrc.pas
Executable file
287
nim/semgnrc.pas
Executable file
|
|
@ -0,0 +1,287 @@
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// The Nimrod Compiler
|
||||||
|
// (c) Copyright 2009 Andreas Rumpf
|
||||||
|
//
|
||||||
|
// See the file "copying.txt", included in this
|
||||||
|
// distribution, for details about the copyright.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
// This implements the first pass over the generic body; it resolves some
|
||||||
|
// symbols. Thus for generics there is a two-phase symbol lookup just like
|
||||||
|
// in C++.
|
||||||
|
// A problem is that it cannot be detected if the symbol is introduced
|
||||||
|
// as in ``var x = ...`` or used because macros/templates can hide this!
|
||||||
|
// So we have to eval templates/macros right here so that symbol
|
||||||
|
// lookup can be accurate.
|
||||||
|
|
||||||
|
type
|
||||||
|
TSemGenericFlag = (withinBind, withinTypeDesc);
|
||||||
|
TSemGenericFlags = set of TSemGenericFlag;
|
||||||
|
|
||||||
|
function semGenericStmt(c: PContext; n: PNode;
|
||||||
|
flags: TSemGenericFlags = {@set}[]): PNode; forward;
|
||||||
|
|
||||||
|
function semGenericStmtScope(c: PContext; n: PNode;
|
||||||
|
flags: TSemGenericFlags = {@set}[]): PNode;
|
||||||
|
begin
|
||||||
|
openScope(c.tab);
|
||||||
|
result := semGenericStmt(c, n, flags);
|
||||||
|
closeScope(c.tab);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function semGenericStmtSymbol(c: PContext; n: PNode; s: PSym): PNode;
|
||||||
|
begin
|
||||||
|
case s.kind of
|
||||||
|
skUnknown: begin
|
||||||
|
// Introduced in this pass! Leave it as an identifier.
|
||||||
|
result := n;
|
||||||
|
end;
|
||||||
|
skProc, skMethod, skIterator, skConverter: result := symChoice(c, n, s);
|
||||||
|
skTemplate: result := semTemplateExpr(c, n, s, false);
|
||||||
|
skMacro: result := semMacroExpr(c, n, s, false);
|
||||||
|
skGenericParam: result := newSymNode(s);
|
||||||
|
skParam: result := n;
|
||||||
|
skType: begin
|
||||||
|
if (s.typ <> nil) and (s.typ.kind <> tyGenericParam) then
|
||||||
|
result := newSymNode(s)
|
||||||
|
else
|
||||||
|
result := n
|
||||||
|
end
|
||||||
|
else result := newSymNode(s)
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
function getIdentNode(n: PNode): PNode;
|
||||||
|
begin
|
||||||
|
case n.kind of
|
||||||
|
nkPostfix: result := getIdentNode(n.sons[1]);
|
||||||
|
nkPragmaExpr, nkAccQuoted: result := getIdentNode(n.sons[0]);
|
||||||
|
nkIdent: result := n;
|
||||||
|
else begin
|
||||||
|
illFormedAst(n);
|
||||||
|
result := nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
function semGenericStmt(c: PContext; n: PNode;
|
||||||
|
flags: TSemGenericFlags = {@set}[]): PNode;
|
||||||
|
var
|
||||||
|
i, j, L: int;
|
||||||
|
a: PNode;
|
||||||
|
s: PSym;
|
||||||
|
begin
|
||||||
|
result := n;
|
||||||
|
if n = nil then exit;
|
||||||
|
case n.kind of
|
||||||
|
nkIdent, nkAccQuoted: begin
|
||||||
|
s := lookUp(c, n);
|
||||||
|
if withinBind in flags then
|
||||||
|
result := symChoice(c, n, s)
|
||||||
|
else
|
||||||
|
result := semGenericStmtSymbol(c, n, s);
|
||||||
|
end;
|
||||||
|
nkDotExpr: begin
|
||||||
|
s := QualifiedLookUp(c, n, true);
|
||||||
|
if s <> nil then
|
||||||
|
result := semGenericStmtSymbol(c, n, s);
|
||||||
|
end;
|
||||||
|
nkSym..nkNilLit: begin end;
|
||||||
|
nkBind: result := semGenericStmt(c, n.sons[0], {@set}[withinBind]);
|
||||||
|
|
||||||
|
nkCall, nkHiddenCallConv, nkInfix, nkPrefix, nkCommand, nkCallStrLit: begin
|
||||||
|
// check if it is an expression macro:
|
||||||
|
checkMinSonsLen(n, 1);
|
||||||
|
s := qualifiedLookup(c, n.sons[0], false);
|
||||||
|
if (s <> nil) then begin
|
||||||
|
case s.kind of
|
||||||
|
skMacro: begin result := semMacroExpr(c, n, s, false); exit end;
|
||||||
|
skTemplate: begin result := semTemplateExpr(c, n, s, false); exit end;
|
||||||
|
skUnknown, skParam: begin
|
||||||
|
// Leave it as an identifier.
|
||||||
|
end;
|
||||||
|
skProc, skMethod, skIterator, skConverter: begin
|
||||||
|
n.sons[0] := symChoice(c, n.sons[0], s);
|
||||||
|
end;
|
||||||
|
skGenericParam: n.sons[0] := newSymNode(s);
|
||||||
|
skType: begin
|
||||||
|
// bad hack for generics:
|
||||||
|
if (s.typ <> nil) and (s.typ.kind <> tyGenericParam) then begin
|
||||||
|
n.sons[0] := newSymNode(s);
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
else n.sons[0] := newSymNode(s)
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
for i := 1 to sonsLen(n)-1 do
|
||||||
|
n.sons[i] := semGenericStmt(c, n.sons[i], flags);
|
||||||
|
end;
|
||||||
|
nkMacroStmt: begin
|
||||||
|
result := semMacroStmt(c, n, false);
|
||||||
|
end;
|
||||||
|
nkIfStmt: begin
|
||||||
|
for i := 0 to sonsLen(n)-1 do
|
||||||
|
n.sons[i] := semGenericStmtScope(c, n.sons[i]);
|
||||||
|
end;
|
||||||
|
nkWhileStmt: begin
|
||||||
|
openScope(c.tab);
|
||||||
|
for i := 0 to sonsLen(n)-1 do
|
||||||
|
n.sons[i] := semGenericStmt(c, n.sons[i]);
|
||||||
|
closeScope(c.tab);
|
||||||
|
end;
|
||||||
|
nkCaseStmt: begin
|
||||||
|
openScope(c.tab);
|
||||||
|
n.sons[0] := semGenericStmt(c, n.sons[0]);
|
||||||
|
for i := 1 to sonsLen(n)-1 do begin
|
||||||
|
a := n.sons[i];
|
||||||
|
checkMinSonsLen(a, 1);
|
||||||
|
L := sonsLen(a);
|
||||||
|
for j := 0 to L-2 do
|
||||||
|
a.sons[j] := semGenericStmt(c, a.sons[j]);
|
||||||
|
a.sons[L-1] := semGenericStmtScope(c, a.sons[L-1]);
|
||||||
|
end;
|
||||||
|
closeScope(c.tab);
|
||||||
|
end;
|
||||||
|
nkForStmt: begin
|
||||||
|
L := sonsLen(n);
|
||||||
|
openScope(c.tab);
|
||||||
|
n.sons[L-2] := semGenericStmt(c, n.sons[L-2]);
|
||||||
|
for i := 0 to L-3 do
|
||||||
|
addDecl(c, newSymS(skUnknown, n.sons[i], c));
|
||||||
|
n.sons[L-1] := semGenericStmt(c, n.sons[L-1]);
|
||||||
|
closeScope(c.tab);
|
||||||
|
end;
|
||||||
|
nkBlockStmt, nkBlockExpr, nkBlockType: begin
|
||||||
|
checkSonsLen(n, 2);
|
||||||
|
openScope(c.tab);
|
||||||
|
if n.sons[0] <> nil then
|
||||||
|
addDecl(c, newSymS(skUnknown, n.sons[0], c));
|
||||||
|
n.sons[1] := semGenericStmt(c, n.sons[1]);
|
||||||
|
closeScope(c.tab);
|
||||||
|
end;
|
||||||
|
nkTryStmt: begin
|
||||||
|
checkMinSonsLen(n, 2);
|
||||||
|
n.sons[0] := semGenericStmtScope(c, n.sons[0]);
|
||||||
|
for i := 1 to sonsLen(n)-1 do begin
|
||||||
|
a := n.sons[i];
|
||||||
|
checkMinSonsLen(a, 1);
|
||||||
|
L := sonsLen(a);
|
||||||
|
for j := 0 to L-2 do
|
||||||
|
a.sons[j] := semGenericStmt(c, a.sons[j], {@set}[withinTypeDesc]);
|
||||||
|
a.sons[L-1] := semGenericStmtScope(c, a.sons[L-1]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
nkVarSection: begin
|
||||||
|
for i := 0 to sonsLen(n)-1 do begin
|
||||||
|
a := n.sons[i];
|
||||||
|
if a.kind = nkCommentStmt then continue;
|
||||||
|
if (a.kind <> nkIdentDefs) and (a.kind <> nkVarTuple) then
|
||||||
|
IllFormedAst(a);
|
||||||
|
checkMinSonsLen(a, 3);
|
||||||
|
L := sonsLen(a);
|
||||||
|
a.sons[L-2] := semGenericStmt(c, a.sons[L-2], {@set}[withinTypeDesc]);
|
||||||
|
a.sons[L-1] := semGenericStmt(c, a.sons[L-1]);
|
||||||
|
for j := 0 to L-3 do
|
||||||
|
addDecl(c, newSymS(skUnknown, getIdentNode(a.sons[j]), c));
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
nkGenericParams: begin
|
||||||
|
for i := 0 to sonsLen(n)-1 do begin
|
||||||
|
a := n.sons[i];
|
||||||
|
if (a.kind <> nkIdentDefs) then IllFormedAst(a);
|
||||||
|
checkMinSonsLen(a, 3);
|
||||||
|
L := sonsLen(a);
|
||||||
|
a.sons[L-2] := semGenericStmt(c, a.sons[L-2], {@set}[withinTypeDesc]);
|
||||||
|
// do not perform symbol lookup for default expressions
|
||||||
|
for j := 0 to L-3 do
|
||||||
|
addDecl(c, newSymS(skUnknown, getIdentNode(a.sons[j]), c));
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
nkConstSection: begin
|
||||||
|
for i := 0 to sonsLen(n)-1 do begin
|
||||||
|
a := n.sons[i];
|
||||||
|
if a.kind = nkCommentStmt then continue;
|
||||||
|
if (a.kind <> nkConstDef) then IllFormedAst(a);
|
||||||
|
checkSonsLen(a, 3);
|
||||||
|
addDecl(c, newSymS(skUnknown, getIdentNode(a.sons[0]), c));
|
||||||
|
a.sons[1] := semGenericStmt(c, a.sons[1], {@set}[withinTypeDesc]);
|
||||||
|
a.sons[2] := semGenericStmt(c, a.sons[2]);
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
nkTypeSection: begin
|
||||||
|
for i := 0 to sonsLen(n)-1 do begin
|
||||||
|
a := n.sons[i];
|
||||||
|
if a.kind = nkCommentStmt then continue;
|
||||||
|
if (a.kind <> nkTypeDef) then IllFormedAst(a);
|
||||||
|
checkSonsLen(a, 3);
|
||||||
|
addDecl(c, newSymS(skUnknown, getIdentNode(a.sons[0]), c));
|
||||||
|
end;
|
||||||
|
for i := 0 to sonsLen(n)-1 do begin
|
||||||
|
a := n.sons[i];
|
||||||
|
if a.kind = nkCommentStmt then continue;
|
||||||
|
if (a.kind <> nkTypeDef) then IllFormedAst(a);
|
||||||
|
checkSonsLen(a, 3);
|
||||||
|
if a.sons[1] <> nil then begin
|
||||||
|
openScope(c.tab);
|
||||||
|
a.sons[1] := semGenericStmt(c, a.sons[1]);
|
||||||
|
a.sons[2] := semGenericStmt(c, a.sons[2], {@set}[withinTypeDesc]);
|
||||||
|
closeScope(c.tab);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
a.sons[2] := semGenericStmt(c, a.sons[2], {@set}[withinTypeDesc]);
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
nkEnumTy: begin
|
||||||
|
checkMinSonsLen(n, 1);
|
||||||
|
if n.sons[0] <> nil then
|
||||||
|
n.sons[0] := semGenericStmt(c, n.sons[0], {@set}[withinTypeDesc]);
|
||||||
|
for i := 1 to sonsLen(n)-1 do begin
|
||||||
|
case n.sons[i].kind of
|
||||||
|
nkEnumFieldDef: a := n.sons[i].sons[0];
|
||||||
|
nkIdent: a := n.sons[i];
|
||||||
|
else illFormedAst(n);
|
||||||
|
end;
|
||||||
|
addDeclAt(c, newSymS(skUnknown, getIdentNode(a.sons[i]), c),
|
||||||
|
c.tab.tos-1);
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
nkObjectTy, nkTupleTy: begin end;
|
||||||
|
nkFormalParams: begin
|
||||||
|
checkMinSonsLen(n, 1);
|
||||||
|
if n.sons[0] <> nil then
|
||||||
|
n.sons[0] := semGenericStmt(c, n.sons[0], {@set}[withinTypeDesc]);
|
||||||
|
for i := 1 to sonsLen(n)-1 do begin
|
||||||
|
a := n.sons[i];
|
||||||
|
if (a.kind <> nkIdentDefs) then IllFormedAst(a);
|
||||||
|
checkMinSonsLen(a, 3);
|
||||||
|
L := sonsLen(a);
|
||||||
|
a.sons[L-1] := semGenericStmt(c, a.sons[L-2], {@set}[withinTypeDesc]);
|
||||||
|
a.sons[L-1] := semGenericStmt(c, a.sons[L-1]);
|
||||||
|
for j := 0 to L-3 do begin
|
||||||
|
addDecl(c, newSymS(skUnknown, getIdentNode(a.sons[j]), c));
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef,
|
||||||
|
nkIteratorDef, nkLambda: begin
|
||||||
|
checkSonsLen(n, codePos+1);
|
||||||
|
addDecl(c, newSymS(skUnknown, getIdentNode(n.sons[0]), c));
|
||||||
|
openScope(c.tab);
|
||||||
|
n.sons[genericParamsPos] := semGenericStmt(c, n.sons[genericParamsPos]);
|
||||||
|
if n.sons[paramsPos] <> nil then begin
|
||||||
|
if n.sons[paramsPos].sons[0] <> nil then
|
||||||
|
addDecl(c, newSym(skUnknown, getIdent('result'), nil));
|
||||||
|
n.sons[paramsPos] := semGenericStmt(c, n.sons[paramsPos]);
|
||||||
|
end;
|
||||||
|
n.sons[pragmasPos] := semGenericStmt(c, n.sons[pragmasPos]);
|
||||||
|
n.sons[codePos] := semGenericStmtScope(c, n.sons[codePos]);
|
||||||
|
closeScope(c.tab);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
for i := 0 to sonsLen(n)-1 do
|
||||||
|
result.sons[i] := semGenericStmt(c, n.sons[i], flags);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
@ -147,7 +147,8 @@ begin
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function resolveTemplateParams(c: PContext; n: PNode; withinBind: bool): PNode;
|
function resolveTemplateParams(c: PContext; n: PNode; withinBind: bool;
|
||||||
|
var toBind: TIntSet): PNode;
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
s: PSym;
|
s: PSym;
|
||||||
|
|
@ -155,7 +156,7 @@ begin
|
||||||
if n = nil then begin result := nil; exit end;
|
if n = nil then begin result := nil; exit end;
|
||||||
case n.kind of
|
case n.kind of
|
||||||
nkIdent: begin
|
nkIdent: begin
|
||||||
if not withinBind then begin
|
if not withinBind and not IntSetContains(toBind, n.ident.id) then begin
|
||||||
s := SymTabLocalGet(c.Tab, n.ident);
|
s := SymTabLocalGet(c.Tab, n.ident);
|
||||||
if (s <> nil) then begin
|
if (s <> nil) then begin
|
||||||
result := newSymNode(s);
|
result := newSymNode(s);
|
||||||
|
|
@ -165,17 +166,18 @@ begin
|
||||||
result := n
|
result := n
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
|
IntSetIncl(toBind, n.ident.id);
|
||||||
result := symChoice(c, n, lookup(c, n))
|
result := symChoice(c, n, lookup(c, n))
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
nkSym..nkNilLit: // atom
|
nkSym..nkNilLit: // atom
|
||||||
result := n;
|
result := n;
|
||||||
nkBind:
|
nkBind:
|
||||||
result := resolveTemplateParams(c, n.sons[0], true);
|
result := resolveTemplateParams(c, n.sons[0], true, toBind);
|
||||||
else begin
|
else begin
|
||||||
result := n;
|
result := n;
|
||||||
for i := 0 to sonsLen(n)-1 do
|
for i := 0 to sonsLen(n)-1 do
|
||||||
result.sons[i] := resolveTemplateParams(c, n.sons[i], withinBind);
|
result.sons[i] := resolveTemplateParams(c, n.sons[i], withinBind, toBind);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
@ -211,6 +213,7 @@ end;
|
||||||
function semTemplateDef(c: PContext; n: PNode): PNode;
|
function semTemplateDef(c: PContext; n: PNode): PNode;
|
||||||
var
|
var
|
||||||
s: PSym;
|
s: PSym;
|
||||||
|
toBind: TIntSet;
|
||||||
begin
|
begin
|
||||||
if c.p.owner.kind = skModule then begin
|
if c.p.owner.kind = skModule then begin
|
||||||
s := semIdentVis(c, skTemplate, n.sons[0], {@set}[sfStar]);
|
s := semIdentVis(c, skTemplate, n.sons[0], {@set}[sfStar]);
|
||||||
|
|
@ -248,7 +251,8 @@ begin
|
||||||
addParams(c, s.typ.n);
|
addParams(c, s.typ.n);
|
||||||
|
|
||||||
// resolve parameters:
|
// resolve parameters:
|
||||||
n.sons[codePos] := resolveTemplateParams(c, n.sons[codePos], false);
|
IntSetInit(toBind);
|
||||||
|
n.sons[codePos] := resolveTemplateParams(c, n.sons[codePos], false, toBind);
|
||||||
if not (s.typ.sons[0].kind in [tyStmt, tyTypeDesc]) then
|
if not (s.typ.sons[0].kind in [tyStmt, tyTypeDesc]) then
|
||||||
n.sons[codePos] := transformToExpr(n.sons[codePos]);
|
n.sons[codePos] := transformToExpr(n.sons[codePos]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
nsystem, strutils, llstream, ast, astalgo, idents, scanner, options, msgs,
|
nsystem, strutils, llstream, ast, astalgo, idents, scanner, options, msgs,
|
||||||
pnimsyn, ptmplsyn, filters, rnimsyn;
|
pnimsyn, pbraces, ptmplsyn, filters, rnimsyn;
|
||||||
|
|
||||||
type
|
type
|
||||||
TFilterKind = (filtNone, filtTemplate, filtReplace, filtStrip);
|
TFilterKind = (filtNone, filtTemplate, filtReplace, filtStrip);
|
||||||
|
|
@ -68,8 +68,8 @@ function parseAll(var p: TParsers): PNode;
|
||||||
begin
|
begin
|
||||||
case p.skin of
|
case p.skin of
|
||||||
skinStandard: result := pnimsyn.parseAll(p.parser);
|
skinStandard: result := pnimsyn.parseAll(p.parser);
|
||||||
skinBraces, skinEndX: InternalError('parser to implement');
|
skinBraces: result := pbraces.parseAll(p.parser);
|
||||||
// skinBraces: result := pbraces.parseAll(p.parser);
|
skinEndX: InternalError('parser to implement');
|
||||||
// skinEndX: result := pendx.parseAll(p.parser);
|
// skinEndX: result := pendx.parseAll(p.parser);
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
@ -78,8 +78,8 @@ function parseTopLevelStmt(var p: TParsers): PNode;
|
||||||
begin
|
begin
|
||||||
case p.skin of
|
case p.skin of
|
||||||
skinStandard: result := pnimsyn.parseTopLevelStmt(p.parser);
|
skinStandard: result := pnimsyn.parseTopLevelStmt(p.parser);
|
||||||
skinBraces, skinEndX: InternalError('parser to implement');
|
skinBraces: result := pbraces.parseTopLevelStmt(p.parser);
|
||||||
//skinBraces: result := pbraces.parseTopLevelStmt(p.parser);
|
skinEndX: InternalError('parser to implement');
|
||||||
//skinEndX: result := pendx.parseTopLevelStmt(p.parser);
|
//skinEndX: result := pendx.parseTopLevelStmt(p.parser);
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
|
||||||
35
nim/vis.pas
Executable file
35
nim/vis.pas
Executable file
|
|
@ -0,0 +1,35 @@
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// The Nimrod Compiler
|
||||||
|
// (c) Copyright 2009 Andreas Rumpf
|
||||||
|
//
|
||||||
|
// See the file "copying.txt", included in this
|
||||||
|
// distribution, for details about the copyright.
|
||||||
|
//
|
||||||
|
unit vis;
|
||||||
|
|
||||||
|
// Virtual instruction set for Nimrod. This is used for LLVM code generation.
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
{$include 'config.inc'}
|
||||||
|
|
||||||
|
uses
|
||||||
|
nsystem, ast, astalgo, strutils, nhashes, trees, platform, magicsys,
|
||||||
|
extccomp, options, nversion, nimsets, msgs, crc, bitsets, idents,
|
||||||
|
lists, types, ccgutils, nos, ntime, ropes, nmath, passes, rodread,
|
||||||
|
wordrecg, rnimsyn, treetab;
|
||||||
|
|
||||||
|
type
|
||||||
|
TInstrKind = (
|
||||||
|
insAddi,
|
||||||
|
|
||||||
|
);
|
||||||
|
TInstruction = record
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
@ -178,7 +178,7 @@ proc buildPdfDoc(c: var TConfigData, destPath: string) =
|
||||||
Exec("pdflatex " & changeFileExt(d, "tex"))
|
Exec("pdflatex " & changeFileExt(d, "tex"))
|
||||||
Exec("pdflatex " & changeFileExt(d, "tex"))
|
Exec("pdflatex " & changeFileExt(d, "tex"))
|
||||||
# delete all the crappy temporary files:
|
# delete all the crappy temporary files:
|
||||||
var pdf = extractFileTrunk(d) & ".pdf"
|
var pdf = splitFile(d).name & ".pdf"
|
||||||
moveFile(destPath / pdf, pdf)
|
moveFile(destPath / pdf, pdf)
|
||||||
removeFile(changeFileExt(pdf, "aux"))
|
removeFile(changeFileExt(pdf, "aux"))
|
||||||
if existsFile(changeFileExt(pdf, "toc")):
|
if existsFile(changeFileExt(pdf, "toc")):
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,14 @@ feature that Nimrod inherited from Lisp is that Nimrod's abstract syntax tree
|
||||||
can be used to create domain specific languages. Nimrod does not sacrifice
|
can be used to create domain specific languages. Nimrod does not sacrifice
|
||||||
flexibility for speed. You get both.
|
flexibility for speed. You get both.
|
||||||
|
|
||||||
|
..
|
||||||
|
Don't give me that marketing crap. What is Nimrod?
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
Nimrod = Mutable value based datatypes + static binding + sugar to make
|
||||||
|
this programming modell as convenient as possible
|
||||||
|
|
||||||
|
|
||||||
How is Nimrod licensed?
|
How is Nimrod licensed?
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue