bind table

This commit is contained in:
Andreas Rumpf
2009-11-12 19:34:21 +01:00
parent d5acb88ccc
commit ac421c37ba
18 changed files with 957 additions and 384 deletions

View File

@@ -20,7 +20,7 @@ contains:
PNimrodNode = ref TNimrodNode
TNimrodNode {.final.} = object
case kind ## the node's kind
case kind: TNimrodNodeKind ## the node's kind
of nnkNone, nnkEmpty, nnkNilLit:
nil ## node contains no additional fields
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(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
================
@@ -72,8 +77,9 @@ Nimrod expression corresponding AST
Identifiers are ``nnkIdent`` nodes. After the name lookup pass these nodes
get transferred into ``nnkSym`` nodes. However, a macro receives an AST that
has not been checked for semantics and thus the identifiers have not been
looked up. 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
=================

View File

@@ -4,8 +4,8 @@ Parsers and Filters
.. contents::
The Nimrod compiler contains multiple parsers. (The standard is
indentation-based.) Two others are available: The `braces`:idx: parser and the
The Nimrod compiler contains multiple parsers. The standard is
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.
To use a different parser for a source file the *shebang* notation is used:

View File

@@ -951,7 +951,7 @@ of the following conditions hold:
3) The procedure has a calling convention that differs from ``nimcall``.
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.
@@ -1800,7 +1800,7 @@ return values. This can be done in a cleaner way by returning a tuple:
assert t.res == 1
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
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
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
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``
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
powerful programming construct that still suffices. So the "check list" is:
@@ -2356,7 +2394,7 @@ verify this.
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.

View File

@@ -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*
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
~~~~~~~~~~~~~~
@@ -231,7 +246,7 @@ compiler to activate (or deactivate) dead code elimination for the module the
pragma appers in.
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 -
no matter if it is globally active or not.
@@ -244,7 +259,7 @@ Example:
Disabling certain messages
--------------------------
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
identifier that can be used to enable or disable it:
@@ -300,9 +315,10 @@ However it is not efficient to do:
.. code-block:: Nimrod
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
efficient than any hand-coded scheme.
..
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
efficient than any hand-coded scheme.
..

View File

@@ -60,6 +60,8 @@ notation meaning
``_`` Any Unicode character: If there is an UTF-8 character
ahead, consume it and indicate success. Otherwise indicate
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`. **Left recursive rules are not possible and crash the
matching engine.**
@@ -118,14 +120,15 @@ The PEG parser implements this grammar (written in PEG syntax)::
"'" ("\\" . / [^'])* "'")
builtin <- "\\" identifier / [^\13\10]
comment <- '#' !\n* \n
comment <- '#' @ \n
ig <- (\s / comment)* # things to ignore
rule <- identifier \s* "<-" expr ig
identNoArrow <- identifier !(\s* "<-")
primary <- (ig '&' / ig '!')* ((ig identNoArrow / ig charset / ig stringlit
/ ig builtin / ig '.' / ig '_'
/ (ig "(" expr ig ")"))
primary <- (ig '&' / ig '!' / ig '@')*
((ig identNoArrow / ig charset / ig stringlit
/ ig builtin / ig '.' / ig '_'
/ (ig "(" expr ig ")"))
(ig '?' / ig '*' / ig '+')*)
# Concatenation has higher priority than choice:
@@ -153,16 +156,16 @@ Determine the ``#include``'ed files of a C file:
.. code-block:: nimrod
for line in lines("myfile.c"):
if line =~ peg"""s <- ws '#include' ws '"' {[^"]+} '"' ws
comment <- '/*' (!'*/' . )* '*/' / '//' .*
ws <- (comment / \s+)* """:
comment <- '/*' @ '*/' / '//' .*
ws <- (comment / \s+)* """:
echo matches[0]
PEG vs regular expression
-------------------------
As a regular expression ``\[.*\]`` maches longest possible text between ``'['``
and ``']'``. As a PEG it never matches anything, because a PEG is
As a regular expression ``\[.*\]`` matches the longest possible text between
``'['`` and ``']'``. As a PEG it never matches anything, because a PEG is
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:
``*`` should not be greedy, so ``\[.*?\]`` should be used.

View File

@@ -7,7 +7,7 @@ Index
`!`:idx:
* `pegs.html#114 <pegs.html#114>`_
* `pegs.html#115 <pegs.html#115>`_
* `macros.html#114 <macros.html#114>`_
`!=`:idx:
@@ -24,7 +24,7 @@ Index
* `system.html#426 <system.html#426>`_
* `times.html#109 <times.html#109>`_
* `times.html#110 <times.html#110>`_
* `pegs.html#148 <pegs.html#148>`_
* `pegs.html#133 <pegs.html#133>`_
* `macros.html#115 <macros.html#115>`_
`%`:idx:
@@ -47,7 +47,7 @@ Index
* `system.html#462 <system.html#462>`_
* `system.html#463 <system.html#463>`_
* `system.html#464 <system.html#464>`_
* `pegs.html#113 <pegs.html#113>`_
* `pegs.html#114 <pegs.html#114>`_
`*`:idx:
* `system.html#212 <system.html#212>`_
@@ -82,7 +82,7 @@ Index
* `system.html#309 <system.html#309>`_
* `system.html#320 <system.html#320>`_
* `complex.html#103 <complex.html#103>`_
* `pegs.html#112 <pegs.html#112>`_
* `pegs.html#113 <pegs.html#113>`_
`+%`:idx:
* `system.html#272 <system.html#272>`_
@@ -152,9 +152,6 @@ Index
* `system.html#346 <system.html#346>`_
* `times.html#114 <times.html#114>`_
`<%`:idx:
`unicode.html#104 <unicode.html#104>`_
`<%`:idx:
* `system.html#302 <system.html#302>`_
* `system.html#303 <system.html#303>`_
@@ -162,6 +159,9 @@ Index
* `system.html#305 <system.html#305>`_
* `system.html#306 <system.html#306>`_
`<%`:idx:
`unicode.html#104 <unicode.html#104>`_
`<=`:idx:
* `system.html#257 <system.html#257>`_
* `system.html#258 <system.html#258>`_
@@ -180,6 +180,9 @@ Index
`<=`:idx:
`times.html#115 <times.html#115>`_
`<=%`:idx:
`unicode.html#103 <unicode.html#103>`_
`<=%`:idx:
* `system.html#297 <system.html#297>`_
* `system.html#298 <system.html#298>`_
@@ -187,9 +190,6 @@ Index
* `system.html#300 <system.html#300>`_
* `system.html#301 <system.html#301>`_
`<=%`:idx:
`unicode.html#103 <unicode.html#103>`_
`==`:idx:
* `md5.html#107 <md5.html#107>`_
* `system.html#252 <system.html#252>`_
@@ -211,12 +211,13 @@ Index
* `complex.html#102 <complex.html#102>`_
* `unicode.html#105 <unicode.html#105>`_
* `macros.html#116 <macros.html#116>`_
* `macros.html#117 <macros.html#117>`_
`=~`:idx:
`pegs.html#138 <pegs.html#138>`_
`regexprs.html#111 <regexprs.html#111>`_
`=~`:idx:
`regexprs.html#108 <regexprs.html#108>`_
`pegs.html#140 <pegs.html#140>`_
`>`:idx:
`system.html#349 <system.html#349>`_
@@ -234,14 +235,15 @@ Index
`pegs.html#110 <pegs.html#110>`_
`@`:idx:
`system.html#357 <system.html#357>`_
`[]`:idx:
`strtabs.html#107 <strtabs.html#107>`_
* `system.html#357 <system.html#357>`_
* `pegs.html#112 <pegs.html#112>`_
`[]`:idx:
`macros.html#112 <macros.html#112>`_
`[]`:idx:
`strtabs.html#107 <strtabs.html#107>`_
`[]=`:idx:
`macros.html#113 <macros.html#113>`_
@@ -279,8 +281,8 @@ Index
* `system.html#368 <system.html#368>`_
* `system.html#369 <system.html#369>`_
* `parsesql.html#108 <parsesql.html#108>`_
* `macros.html#118 <macros.html#118>`_
* `macros.html#119 <macros.html#119>`_
* `macros.html#120 <macros.html#120>`_
`addf`:idx:
`strutils.html#111 <strutils.html#111>`_
@@ -332,17 +334,17 @@ Index
* `system.html#241 <system.html#241>`_
`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>`_
`anyRune`:idx:
`any character`:idx:
`pegs.html#116 <pegs.html#116>`_
`any rune`:idx:
`pegs.html#118 <pegs.html#118>`_
`anyRune`:idx:
`pegs.html#119 <pegs.html#119>`_
`apostrophe`:idx:
`manual.html#129 <manual.html#129>`_
@@ -403,7 +405,8 @@ Index
`xmlgen.html#111 <xmlgen.html#111>`_
`backslash`:idx:
`manual.html#127 <manual.html#127>`_
* `manual.html#127 <manual.html#127>`_
* `regexprs.html#101 <regexprs.html#101>`_
`backspace`:idx:
`manual.html#132 <manual.html#132>`_
@@ -476,7 +479,7 @@ Index
`xmlgen.html#118 <xmlgen.html#118>`_
`capture`:idx:
`pegs.html#121 <pegs.html#121>`_
`pegs.html#122 <pegs.html#122>`_
`card`:idx:
`system.html#175 <system.html#175>`_
@@ -695,12 +698,12 @@ Index
`CompileDate`:idx:
`system.html#390 <system.html#390>`_
`CompileTime`:idx:
`system.html#391 <system.html#391>`_
`compileTime`:idx:
`manual.html#229 <manual.html#229>`_
`CompileTime`:idx:
`system.html#391 <system.html#391>`_
`complex statements`:idx:
`manual.html#178 <manual.html#178>`_
@@ -719,8 +722,8 @@ Index
* `strutils.html#137 <strutils.html#137>`_
* `strutils.html#138 <strutils.html#138>`_
* `strutils.html#139 <strutils.html#139>`_
* `pegs.html#139 <pegs.html#139>`_
* `pegs.html#140 <pegs.html#140>`_
* `pegs.html#141 <pegs.html#141>`_
* `pegs.html#142 <pegs.html#142>`_
`continue`:idx:
`manual.html#198 <manual.html#198>`_
@@ -736,10 +739,10 @@ Index
`system.html#407 <system.html#407>`_
`copyNimNode`:idx:
`macros.html#135 <macros.html#135>`_
`macros.html#136 <macros.html#136>`_
`copyNimTree`:idx:
`macros.html#136 <macros.html#136>`_
`macros.html#137 <macros.html#137>`_
`coreAttr`:idx:
`xmlgen.html#103 <xmlgen.html#103>`_
@@ -1185,7 +1188,7 @@ Index
`del`:idx:
* `xmlgen.html#124 <xmlgen.html#124>`_
* `macros.html#120 <macros.html#120>`_
* `macros.html#121 <macros.html#121>`_
`delete`:idx:
`strutils.html#156 <strutils.html#156>`_
@@ -1198,7 +1201,7 @@ Index
`xmlgen.html#125 <xmlgen.html#125>`_
`digits`:idx:
`pegs.html#125 <pegs.html#125>`_
`pegs.html#126 <pegs.html#126>`_
`Digits`:idx:
`strutils.html#104 <strutils.html#104>`_
@@ -1290,10 +1293,10 @@ Index
`system.html#160 <system.html#160>`_
`EInvalidPeg`:idx:
`pegs.html#149 <pegs.html#149>`_
`pegs.html#150 <pegs.html#150>`_
`EInvalidRegEx`:idx:
`regexprs.html#101 <regexprs.html#101>`_
`regexprs.html#104 <regexprs.html#104>`_
`EInvalidSql`:idx:
`parsesql.html#103 <parsesql.html#103>`_
@@ -1322,7 +1325,7 @@ Index
`endsWith`:idx:
* `strutils.html#148 <strutils.html#148>`_
* `pegs.html#142 <pegs.html#142>`_
* `pegs.html#144 <pegs.html#144>`_
`ENoExceptionToReraise`:idx:
* `manual.html#187 <manual.html#187>`_
@@ -1334,12 +1337,12 @@ Index
`enum_cursor_type`:idx:
`mysql.html#237 <mysql.html#237>`_
`Enumeration`:idx:
`manual.html#149 <manual.html#149>`_
`enumeration`:idx:
`tut1.html#113 <tut1.html#113>`_
`Enumeration`:idx:
`manual.html#149 <manual.html#149>`_
`enum_field_types`:idx:
`mysql.html#202 <mysql.html#202>`_
@@ -1390,7 +1393,7 @@ Index
`error`:idx:
* `manual.html#226 <manual.html#226>`_
* `manual.html#230 <manual.html#230>`_
* `macros.html#137 <macros.html#137>`_
* `macros.html#138 <macros.html#138>`_
`errorMsg`:idx:
`parsexml.html#120 <parsexml.html#120>`_
@@ -1478,13 +1481,13 @@ Index
`os.html#132 <os.html#132>`_
`expectKind`:idx:
`macros.html#146 <macros.html#146>`_
`macros.html#147 <macros.html#147>`_
`expectLen`:idx:
`macros.html#148 <macros.html#148>`_
`macros.html#149 <macros.html#149>`_
`expectMinLen`:idx:
`macros.html#147 <macros.html#147>`_
`macros.html#148 <macros.html#148>`_
`exportc`:idx:
`nimrodc.html#102 <nimrodc.html#102>`_
@@ -1632,10 +1635,10 @@ Index
* `strutils.html#119 <strutils.html#119>`_
* `strutils.html#120 <strutils.html#120>`_
* `strutils.html#121 <strutils.html#121>`_
* `regexprs.html#106 <regexprs.html#106>`_
* `regexprs.html#107 <regexprs.html#107>`_
* `pegs.html#136 <pegs.html#136>`_
* `pegs.html#137 <pegs.html#137>`_
* `regexprs.html#109 <regexprs.html#109>`_
* `regexprs.html#110 <regexprs.html#110>`_
* `pegs.html#138 <pegs.html#138>`_
* `pegs.html#139 <pegs.html#139>`_
`float`:idx:
`system.html#106 <system.html#106>`_
@@ -1647,10 +1650,10 @@ Index
`system.html#108 <system.html#108>`_
`floatVal`:idx:
`macros.html#123 <macros.html#123>`_
`macros.html#124 <macros.html#124>`_
`floatVal=`:idx:
`macros.html#129 <macros.html#129>`_
`macros.html#130 <macros.html#130>`_
`FlushFile`:idx:
`system.html#503 <system.html#503>`_
@@ -1715,6 +1718,9 @@ Index
`generalized raw string literal`:idx:
`manual.html#136 <manual.html#136>`_
`generic character types`:idx:
`regexprs.html#102 <regexprs.html#102>`_
`Generics`:idx:
* `manual.html#212 <manual.html#212>`_
* `tut2.html#109 <tut2.html#109>`_
@@ -1987,7 +1993,7 @@ Index
`hint`:idx:
* `manual.html#224 <manual.html#224>`_
* `manual.html#233 <manual.html#233>`_
* `macros.html#139 <macros.html#139>`_
* `macros.html#140 <macros.html#140>`_
`hostCPU`:idx:
`system.html#398 <system.html#398>`_
@@ -2001,13 +2007,13 @@ Index
`hr`:idx:
`xmlgen.html#140 <xmlgen.html#140>`_
`html`:idx:
`xmlgen.html#139 <xmlgen.html#139>`_
`HTML`:idx:
* `parsexml.html#102 <parsexml.html#102>`_
* `xmlgen.html#102 <xmlgen.html#102>`_
`html`:idx:
`xmlgen.html#139 <xmlgen.html#139>`_
`HTTPPOST_BUFFER`:idx:
`libcurl.html#266 <libcurl.html#266>`_
@@ -2033,14 +2039,14 @@ Index
`xmlgen.html#141 <xmlgen.html#141>`_
`ident`:idx:
* `pegs.html#129 <pegs.html#129>`_
* `macros.html#125 <macros.html#125>`_
* `pegs.html#130 <pegs.html#130>`_
* `macros.html#126 <macros.html#126>`_
`ident=`:idx:
`macros.html#131 <macros.html#131>`_
`macros.html#132 <macros.html#132>`_
`identChars`:idx:
`pegs.html#127 <pegs.html#127>`_
`pegs.html#128 <pegs.html#128>`_
`IdentChars`:idx:
`strutils.html#105 <strutils.html#105>`_
@@ -2052,7 +2058,7 @@ Index
`manual.html#116 <manual.html#116>`_
`identStartChars`:idx:
`pegs.html#128 <pegs.html#128>`_
`pegs.html#129 <pegs.html#129>`_
`IdentStartChars`:idx:
`strutils.html#106 <strutils.html#106>`_
@@ -2138,10 +2144,10 @@ Index
`strutils.html#141 <strutils.html#141>`_
`intVal`:idx:
`macros.html#122 <macros.html#122>`_
`macros.html#123 <macros.html#123>`_
`intVal=`:idx:
`macros.html#128 <macros.html#128>`_
`macros.html#129 <macros.html#129>`_
`is`:idx:
`system.html#353 <system.html#353>`_
@@ -2226,7 +2232,7 @@ Index
`kind`:idx:
* `parsexml.html#110 <parsexml.html#110>`_
* `macros.html#121 <macros.html#121>`_
* `macros.html#122 <macros.html#122>`_
`l-values`:idx:
`manual.html#107 <manual.html#107>`_
@@ -2245,13 +2251,13 @@ Index
* `system.html#172 <system.html#172>`_
* `strtabs.html#109 <strtabs.html#109>`_
* `parsesql.html#107 <parsesql.html#107>`_
* `macros.html#117 <macros.html#117>`_
* `macros.html#118 <macros.html#118>`_
`Letters`:idx:
`strutils.html#103 <strutils.html#103>`_
`letters`:idx:
`pegs.html#124 <pegs.html#124>`_
`pegs.html#125 <pegs.html#125>`_
`li`:idx:
`xmlgen.html#148 <xmlgen.html#148>`_
@@ -2353,16 +2359,16 @@ Index
`xmlgen.html#150 <xmlgen.html#150>`_
`match`:idx:
* `regexprs.html#103 <regexprs.html#103>`_
* `regexprs.html#104 <regexprs.html#104>`_
* `pegs.html#132 <pegs.html#132>`_
* `pegs.html#133 <pegs.html#133>`_
`matchLen`:idx:
* `regexprs.html#105 <regexprs.html#105>`_
* `regexprs.html#106 <regexprs.html#106>`_
* `regexprs.html#107 <regexprs.html#107>`_
* `pegs.html#134 <pegs.html#134>`_
* `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:
* `system.html#318 <system.html#318>`_
* `system.html#444 <system.html#444>`_
@@ -2397,8 +2403,8 @@ Index
`mysql.html#191 <mysql.html#191>`_
`MaxSubpatterns`:idx:
* `regexprs.html#102 <regexprs.html#102>`_
* `pegs.html#131 <pegs.html#131>`_
* `regexprs.html#105 <regexprs.html#105>`_
* `pegs.html#132 <pegs.html#132>`_
`MAX_TINYINT_WIDTH`:idx:
`mysql.html#190 <mysql.html#190>`_
@@ -2990,13 +2996,13 @@ Index
`system.html#134 <system.html#134>`_
`natural`:idx:
`pegs.html#130 <pegs.html#130>`_
`pegs.html#131 <pegs.html#131>`_
`neginf`:idx:
`system.html#430 <system.html#430>`_
`nestList`:idx:
`macros.html#151 <macros.html#151>`_
`macros.html#152 <macros.html#152>`_
`NET`:idx:
`mysql.html#199 <mysql.html#199>`_
@@ -3042,38 +3048,38 @@ Index
* `system.html#125 <system.html#125>`_
`newCall`:idx:
* `macros.html#149 <macros.html#149>`_
* `macros.html#150 <macros.html#150>`_
* `macros.html#151 <macros.html#151>`_
`newFileStream`:idx:
* `streams.html#120 <streams.html#120>`_
* `streams.html#121 <streams.html#121>`_
`newFloatLitNode`:idx:
`macros.html#142 <macros.html#142>`_
`macros.html#143 <macros.html#143>`_
`newIdentNode`:idx:
* `macros.html#143 <macros.html#143>`_
* `macros.html#144 <macros.html#144>`_
* `macros.html#145 <macros.html#145>`_
`newIntLitNode`:idx:
`macros.html#141 <macros.html#141>`_
`macros.html#142 <macros.html#142>`_
`newLine`:idx:
`pegs.html#121 <pegs.html#121>`_
`newline`:idx:
* `manual.html#121 <manual.html#121>`_
* `pegs.html#119 <pegs.html#119>`_
`newLine`:idx:
`pegs.html#120 <pegs.html#120>`_
* `pegs.html#120 <pegs.html#120>`_
`NewLines`:idx:
`lexbase.html#102 <lexbase.html#102>`_
`newNimNode`:idx:
`macros.html#134 <macros.html#134>`_
`macros.html#135 <macros.html#135>`_
`newNonTerminal`:idx:
`pegs.html#123 <pegs.html#123>`_
`pegs.html#124 <pegs.html#124>`_
`newSeq`:idx:
`system.html#167 <system.html#167>`_
@@ -3089,7 +3095,7 @@ Index
* `strtabs.html#105 <strtabs.html#105>`_
`newStrLitNode`:idx:
`macros.html#140 <macros.html#140>`_
`macros.html#141 <macros.html#141>`_
`next`:idx:
* `parseopt.html#105 <parseopt.html#105>`_
@@ -3124,7 +3130,7 @@ Index
`mysql.html#136 <mysql.html#136>`_
`nonterminal`:idx:
`pegs.html#122 <pegs.html#122>`_
`pegs.html#123 <pegs.html#123>`_
`normalize`:idx:
`strutils.html#118 <strutils.html#118>`_
@@ -3238,7 +3244,7 @@ Index
`strtabs.html#110 <strtabs.html#110>`_
`parallelReplace`:idx:
`pegs.html#144 <pegs.html#144>`_
`pegs.html#146 <pegs.html#146>`_
`param`:idx:
`xmlgen.html#158 <xmlgen.html#158>`_
@@ -3268,7 +3274,7 @@ Index
`strutils.html#142 <strutils.html#142>`_
`parsePeg`:idx:
`pegs.html#150 <pegs.html#150>`_
`pegs.html#151 <pegs.html#151>`_
`parseSQL`:idx:
`parsesql.html#109 <parsesql.html#109>`_
@@ -3403,7 +3409,7 @@ Index
`libcurl.html#122 <libcurl.html#122>`_
`peg`:idx:
`pegs.html#151 <pegs.html#151>`_
`pegs.html#152 <pegs.html#152>`_
`Pfd_set`:idx:
`libcurl.html#138 <libcurl.html#138>`_
@@ -3771,16 +3777,16 @@ Index
`system.html#412 <system.html#412>`_
`reBinary`:idx:
`regexprs.html#113 <regexprs.html#113>`_
`regexprs.html#116 <regexprs.html#116>`_
`Recursive module dependancies`:idx:
`manual.html#221 <manual.html#221>`_
`reEmail`:idx:
`regexprs.html#116 <regexprs.html#116>`_
`regexprs.html#119 <regexprs.html#119>`_
`reFloat`:idx:
`regexprs.html#115 <regexprs.html#115>`_
`regexprs.html#118 <regexprs.html#118>`_
`REFRESH_DES_KEY_FILE`:idx:
`mysql.html#154 <mysql.html#154>`_
@@ -3828,13 +3834,13 @@ Index
`nimrodc.html#112 <nimrodc.html#112>`_
`reHex`:idx:
`regexprs.html#112 <regexprs.html#112>`_
`regexprs.html#115 <regexprs.html#115>`_
`reIdentifier`:idx:
`regexprs.html#109 <regexprs.html#109>`_
`regexprs.html#112 <regexprs.html#112>`_
`reInteger`:idx:
`regexprs.html#111 <regexprs.html#111>`_
`regexprs.html#114 <regexprs.html#114>`_
`removeDir`:idx:
`os.html#158 <os.html#158>`_
@@ -3843,13 +3849,13 @@ Index
`os.html#144 <os.html#144>`_
`reNatural`:idx:
`regexprs.html#110 <regexprs.html#110>`_
`regexprs.html#113 <regexprs.html#113>`_
`renderSQL`:idx:
`parsesql.html#110 <parsesql.html#110>`_
`reOctal`:idx:
`regexprs.html#114 <regexprs.html#114>`_
`regexprs.html#117 <regexprs.html#117>`_
`repeatChar`:idx:
`strutils.html#146 <strutils.html#146>`_
@@ -3857,7 +3863,7 @@ Index
`replace`:idx:
* `strutils.html#154 <strutils.html#154>`_
* `strutils.html#155 <strutils.html#155>`_
* `pegs.html#143 <pegs.html#143>`_
* `pegs.html#145 <pegs.html#145>`_
`replaceStr`:idx:
* `strutils.html#122 <strutils.html#122>`_
@@ -3880,7 +3886,7 @@ Index
`manual.html#192 <manual.html#192>`_
`reURL`:idx:
`regexprs.html#117 <regexprs.html#117>`_
`regexprs.html#120 <regexprs.html#120>`_
`round`:idx:
`math.html#121 <math.html#121>`_
@@ -4048,6 +4054,9 @@ Index
* `system.html#230 <system.html#230>`_
* `system.html#231 <system.html#231>`_
`simple assertions`:idx:
`regexprs.html#103 <regexprs.html#103>`_
`simple statements`:idx:
`manual.html#177 <manual.html#177>`_
@@ -4074,8 +4083,8 @@ Index
* `strutils.html#127 <strutils.html#127>`_
* `strutils.html#133 <strutils.html#133>`_
* `strutils.html#134 <strutils.html#134>`_
* `pegs.html#146 <pegs.html#146>`_
* `pegs.html#147 <pegs.html#147>`_
* `pegs.html#148 <pegs.html#148>`_
* `pegs.html#149 <pegs.html#149>`_
`splitFile`:idx:
`os.html#129 <os.html#129>`_
@@ -4611,7 +4620,7 @@ Index
`startsWith`:idx:
* `strutils.html#147 <strutils.html#147>`_
* `pegs.html#141 <pegs.html#141>`_
* `pegs.html#143 <pegs.html#143>`_
`statement macros`:idx:
`tut2.html#112 <tut2.html#112>`_
@@ -4702,10 +4711,10 @@ Index
`manual.html#152 <manual.html#152>`_
`strVal`:idx:
`macros.html#127 <macros.html#127>`_
`macros.html#128 <macros.html#128>`_
`strVal=`:idx:
`macros.html#133 <macros.html#133>`_
`macros.html#134 <macros.html#134>`_
`st_udf_args`:idx:
`mysql.html#258 <mysql.html#258>`_
@@ -4751,10 +4760,10 @@ Index
`dynlib.html#104 <dynlib.html#104>`_
`symbol`:idx:
`macros.html#124 <macros.html#124>`_
`macros.html#125 <macros.html#125>`_
`symbol=`:idx:
`macros.html#130 <macros.html#130>`_
`macros.html#131 <macros.html#131>`_
`syscall`:idx:
`manual.html#172 <manual.html#172>`_
@@ -5114,7 +5123,7 @@ Index
`strutils.html#145 <strutils.html#145>`_
`toStrLit`:idx:
`macros.html#145 <macros.html#145>`_
`macros.html#146 <macros.html#146>`_
`toTitle`:idx:
`unicode.html#113 <unicode.html#113>`_
@@ -5153,7 +5162,7 @@ Index
* `tut1.html#121 <tut1.html#121>`_
`transformFile`:idx:
`pegs.html#145 <pegs.html#145>`_
`pegs.html#147 <pegs.html#147>`_
`TRequestMethod`:idx:
`cgi.html#105 <cgi.html#105>`_
@@ -5244,10 +5253,10 @@ Index
`parsexml.html#106 <parsexml.html#106>`_
`typ`:idx:
`macros.html#126 <macros.html#126>`_
`macros.html#127 <macros.html#127>`_
`typ=`:idx:
`macros.html#132 <macros.html#132>`_
`macros.html#133 <macros.html#133>`_
`type`:idx:
* `manual.html#102 <manual.html#102>`_
@@ -5363,7 +5372,7 @@ Index
* `tut2.html#103 <tut2.html#103>`_
`verbose`:idx:
`regexprs.html#118 <regexprs.html#118>`_
`regexprs.html#121 <regexprs.html#121>`_
`vertical tabulator`:idx:
`manual.html#126 <manual.html#126>`_
@@ -5387,7 +5396,7 @@ Index
`warning`:idx:
* `manual.html#225 <manual.html#225>`_
* `manual.html#232 <manual.html#232>`_
* `macros.html#138 <macros.html#138>`_
* `macros.html#139 <macros.html#139>`_
`when`:idx:
* `manual.html#185 <manual.html#185>`_
@@ -5400,7 +5409,7 @@ Index
`strutils.html#102 <strutils.html#102>`_
`whitespace`:idx:
`pegs.html#126 <pegs.html#126>`_
`pegs.html#127 <pegs.html#127>`_
`winTimeToUnixTime`:idx:
`times.html#118 <times.html#118>`_

View File

@@ -42,7 +42,7 @@ type
pkSequence, ## a b c ... --> Internal DSL: peg(a, b, c)
pkOrderedChoice, ## a / b / ... --> Internal DSL: a / b or /[a, b, c]
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)
pkGreedyRepSet, ## [set]* (superop)
pkGreedyAny, ## .* or _* (superop)
@@ -50,6 +50,7 @@ type
pkAndPredicate, ## &a --> Internal DSL: &a
pkNotPredicate, ## !a --> Internal DSL: !a
pkCapture, ## {a} --> Internal DSL: capture(a)
pkSearch, ## @a --> Internal DSL: @a
pkRule, ## a <- b
pkList ## a, b
TNonTerminalFlag = enum
@@ -174,7 +175,24 @@ proc `*`*(a: TPeg): TPeg =
else:
result.kind = pkGreedyRep
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 =
## constructs a "greedy positive repetition" with the PEG `a`
return sequence(a, *a)
@@ -271,6 +289,125 @@ const
MaxSubpatterns* = 10 ## defines the maximum number of subpatterns that
## 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 -------------------------------------------
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)
if result >= 0: break
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:
result = 0
while true:
@@ -607,123 +755,6 @@ proc split*(s: string, sep: TPeg): seq[string] {.noSideEffect.} =
## Splits the string `s` into substrings.
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 -------------------------------------------------
type
@@ -751,6 +782,7 @@ type
tkAmp, ## '&'
tkNot, ## '!'
tkOption, ## '?'
tkAt, ## '@'
tkBuiltin, ## \identifier
tkEscaped ## \\
@@ -772,7 +804,7 @@ const
tokKindToStr: array[TTokKind, string] = [
"invalid", "[EOF]", ".", "_", "identifier", "string literal",
"character set", "(", ")", "{", "}", "<-", "/", "*", "+", "&", "!", "?",
"built-in", "escaped"
"@", "built-in", "escaped"
]
proc HandleCR(L: var TPegLexer, pos: int): int =
@@ -1063,6 +1095,10 @@ proc getTok(c: var TPegLexer, tok: var TToken) =
tok.kind = tkAmp
inc(c.bufpos)
add(tok.literal, '!')
of '@':
tok.kind = tkAt
inc(c.bufpos)
add(tok.literal, '@')
else:
add(tok.literal, c.buf[c.bufpos])
inc(c.bufpos)
@@ -1118,6 +1154,9 @@ proc primary(p: var TPegParser): TPeg =
of tkNot:
getTok(p)
return !primary(p)
of tkAt:
getTok(p)
return @primary(p)
else: nil
case p.tok.kind
of tkIdentifier:
@@ -1187,7 +1226,7 @@ proc seqExpr(p: var TPegParser): TPeg =
result = primary(p)
while true:
case p.tok.kind
of tkAmp, tkNot, tkStringLit, tkCharset, tkParLe, tkCurlyLe,
of tkAmp, tkNot, tkAt, tkStringLit, tkCharset, tkParLe, tkCurlyLe,
tkAny, tkAnyRune, tkBuiltin, tkEscaped:
result = sequence(result, primary(p))
of tkIdentifier:
@@ -1261,6 +1300,7 @@ proc peg*(pattern: string): TPeg =
result = parsePeg(pattern, "pattern")
when isMainModule:
assert match("(a b c)", peg"'(' @ ')'")
assert match("W_HI_Le", peg"\y 'while'")
assert(not match("W_HI_L", peg"\y 'while'"))
assert(not match("W_HI_Le", peg"\y v'while'"))
@@ -1315,6 +1355,11 @@ when isMainModule:
"""
assert($g2 == "((A B) / (C D))")
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}")
if "aaaaaa" =~ peg"'aa' !. / ({'a'})+":
assert matches[0] == "a"
else:
assert false

View File

@@ -44,15 +44,13 @@ proc runeLenAt*(s: string, i: int): int =
template fastRuneAt*(s: string, i: int, result: expr, 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.
when not defined(ones):
template ones(n: expr): expr = ((1 shl n)-1)
if ord(s[i]) <=% 127:
result = TRune(ord(s[i]))
when doInc: inc(i)
elif ord(s[i]) shr 5 == 0b110:
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)
elif ord(s[i]) shr 4 == 0b1110:
assert(ord(s[i+1]) shr 6 == 0b10)

139
nim/llvmdata.pas Executable file
View 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.

View File

@@ -146,8 +146,7 @@ begin
end;
end;
procedure qualifiedIdentListAux(var p: TParser; endTok: TTokType;
result: PNode);
procedure qualifiedIdentListAux(var p: TParser; endTok: TTokType; result: PNode);
var
a: PNode;
begin
@@ -216,16 +215,6 @@ begin
eat(p, tkParRi);
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;
begin
case p.tok.tokType of
@@ -542,7 +531,7 @@ begin
optInd(p, result);
while (p.tok.tokType = tkSymbol) or (p.tok.tokType = tkAccent) do begin
a := parseIdentColonEquals(p, {@set}[]);
addSon(result, a);
addSon(result, a);
if p.tok.tokType <> tkComma then break;
getTok(p);
optInd(p, a)
@@ -729,12 +718,12 @@ begin
end
end;
function parseImportStmt(var p: TParser): PNode;
function parseImportOrIncludeStmt(var p: TParser; kind: TNodeKind): PNode;
var
a: PNode;
begin
result := newNodeP(nkImportStmt, p);
getTok(p); // skip `import`
result := newNodeP(kind, p);
getTok(p); // skip `import` or `include`
optInd(p, result);
while true do begin
case p.tok.tokType of
@@ -764,41 +753,6 @@ begin
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;
var
a: PNode;
@@ -1150,6 +1104,24 @@ begin
indAndComment(p, result); // XXX: special extension!
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;
var
a, b: PNode;
@@ -1379,9 +1351,9 @@ begin
tkBreak: result := parseBreakOrContinue(p, nkBreakStmt);
tkContinue: result := parseBreakOrContinue(p, nkContinueStmt);
tkCurlyDotLe: result := parsePragma(p);
tkImport: result := parseImportStmt(p);
tkImport: result := parseImportOrIncludeStmt(p, nkImportStmt);
tkFrom: result := parseFromStmt(p);
tkInclude: result := parseIncludeStmt(p);
tkInclude: result := parseImportOrIncludeStmt(p, nkIncludeStmt);
tkComment: result := newCommentStmt(p);
else begin
if isExprStart(p) then
@@ -1394,6 +1366,24 @@ begin
skipComment(p, result);
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;
begin
case p.tok.tokType of
@@ -1410,8 +1400,9 @@ begin
tkMacro: result := parseRoutine(p, nkMacroDef);
tkTemplate: result := parseRoutine(p, nkTemplateDef);
tkConverter: result := parseRoutine(p, nkConverterDef);
tkType: result := parseSection(p, nkTypeSection, parseTypeDef);
tkConst: result := parseSection(p, nkConstSection, parseConstant);
tkType, tkEnum, tkObject, tkTuple:
result := parseTypeAlias(p, nkTypeSection, parseTypeDef);
tkConst: result := parseConstSection(p);
tkWhen: result := parseIfOrWhen(p, nkWhenStmt);
tkVar: result := parseSection(p, nkVarSection, parseVariable);
else result := simpleStmt(p);
@@ -1422,15 +1413,13 @@ function parseStmt(var p: TParser): PNode;
var
a: PNode;
begin
if p.tok.tokType = tkInd then begin
if p.tok.tokType = tkCurlyLe then begin
result := newNodeP(nkStmtList, p);
pushInd(p.lex^, p.tok.indent);
getTok(p);
while true do begin
case p.tok.tokType of
tkSad: getTok(p);
tkEof: break;
tkDed: begin getTok(p); break end;
tkSad, tkInd, tkDed: getTok(p);
tkEof, tkCurlyRi: break;
else begin
a := complexOrSimpleStmt(p);
if a = nil then break;
@@ -1438,7 +1427,7 @@ begin
end
end
end;
popInd(p.lex^);
eat(p, tkCurlyRi);
end
else begin
// the case statement is only needed for better error messages:
@@ -1451,7 +1440,7 @@ begin
else begin
result := simpleStmt(p);
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
@@ -1464,8 +1453,7 @@ begin
result := newNodeP(nkStmtList, p);
while true do begin
case p.tok.tokType of
tkSad: getTok(p);
tkDed, tkInd: parMessage(p, errInvalidIndentation);
tkDed, tkInd, tkSad: getTok(p);
tkEof: break;
else begin
a := complexOrSimpleStmt(p);
@@ -1481,11 +1469,7 @@ begin
result := nil;
while true do begin
case p.tok.tokType of
tkSad: getTok(p);
tkDed, tkInd: begin
parMessage(p, errInvalidIndentation);
break;
end;
tkDed, tkInd, tkSad: getTok(p);
tkEof: break;
else begin
result := complexOrSimpleStmt(p);

36
nim/pendx.pas Executable file
View 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.

View File

@@ -72,6 +72,7 @@ procedure optSad(var p: TParser);
procedure optInd(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 accExpr(var p: TParser): PNode;
@@ -1069,12 +1070,12 @@ begin
end
end;
function parseImportStmt(var p: TParser): PNode;
function parseImportOrIncludeStmt(var p: TParser; kind: TNodeKind): PNode;
var
a: PNode;
begin
result := newNodeP(nkImportStmt, p);
getTok(p); // skip `import`
result := newNodeP(kind, p);
getTok(p); // skip `import` or `include`
optInd(p, result);
while true do begin
case p.tok.tokType of
@@ -1104,42 +1105,6 @@ begin
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;
var
a: PNode;
@@ -1717,9 +1682,9 @@ begin
tkBreak: result := parseBreakOrContinue(p, nkBreakStmt);
tkContinue: result := parseBreakOrContinue(p, nkContinueStmt);
tkCurlyDotLe: result := parsePragma(p);
tkImport: result := parseImportStmt(p);
tkImport: result := parseImportOrIncludeStmt(p, nkImportStmt);
tkFrom: result := parseFromStmt(p);
tkInclude: result := parseIncludeStmt(p);
tkInclude: result := parseImportOrIncludeStmt(p, nkIncludeStmt);
tkComment: result := newCommentStmt(p);
else begin
if isExprStart(p) then

287
nim/semgnrc.pas Executable file
View 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;

View File

@@ -147,7 +147,8 @@ begin
end
end;
function resolveTemplateParams(c: PContext; n: PNode; withinBind: bool): PNode;
function resolveTemplateParams(c: PContext; n: PNode; withinBind: bool;
var toBind: TIntSet): PNode;
var
i: int;
s: PSym;
@@ -155,7 +156,7 @@ begin
if n = nil then begin result := nil; exit end;
case n.kind of
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);
if (s <> nil) then begin
result := newSymNode(s);
@@ -165,17 +166,18 @@ begin
result := n
end
else begin
IntSetIncl(toBind, n.ident.id);
result := symChoice(c, n, lookup(c, n))
end
end;
nkSym..nkNilLit: // atom
result := n;
nkBind:
result := resolveTemplateParams(c, n.sons[0], true);
result := resolveTemplateParams(c, n.sons[0], true, toBind);
else begin
result := n;
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;
@@ -211,6 +213,7 @@ end;
function semTemplateDef(c: PContext; n: PNode): PNode;
var
s: PSym;
toBind: TIntSet;
begin
if c.p.owner.kind = skModule then begin
s := semIdentVis(c, skTemplate, n.sons[0], {@set}[sfStar]);
@@ -248,7 +251,8 @@ begin
addParams(c, s.typ.n);
// 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
n.sons[codePos] := transformToExpr(n.sons[codePos]);

View File

@@ -15,7 +15,7 @@ interface
uses
nsystem, strutils, llstream, ast, astalgo, idents, scanner, options, msgs,
pnimsyn, ptmplsyn, filters, rnimsyn;
pnimsyn, pbraces, ptmplsyn, filters, rnimsyn;
type
TFilterKind = (filtNone, filtTemplate, filtReplace, filtStrip);
@@ -68,8 +68,8 @@ function parseAll(var p: TParsers): PNode;
begin
case p.skin of
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);
end
end;
@@ -78,8 +78,8 @@ function parseTopLevelStmt(var p: TParsers): PNode;
begin
case p.skin of
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);
end
end;

35
nim/vis.pas Executable file
View 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.

View File

@@ -178,7 +178,7 @@ proc buildPdfDoc(c: var TConfigData, destPath: string) =
Exec("pdflatex " & changeFileExt(d, "tex"))
Exec("pdflatex " & changeFileExt(d, "tex"))
# delete all the crappy temporary files:
var pdf = extractFileTrunk(d) & ".pdf"
var pdf = splitFile(d).name & ".pdf"
moveFile(destPath / pdf, pdf)
removeFile(changeFileExt(pdf, "aux"))
if existsFile(changeFileExt(pdf, "toc")):

View File

@@ -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
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?
-----------------------