Integrating my changes, mostly minor/cosmetic fixes; plus a big Windows lib update
This commit is contained in:
parent
227b76c342
commit
286e5958d6
37 changed files with 30552 additions and 30077 deletions
|
|
@ -10,7 +10,7 @@ Advanced options:
|
||||||
--warning[X]:on|off turn specific warning X on|off
|
--warning[X]:on|off turn specific warning X on|off
|
||||||
--hints:on|off turn all hints on|off
|
--hints:on|off turn all hints on|off
|
||||||
--hint[X]:on|off turn specific hint X on|off
|
--hint[X]:on|off turn specific hint X on|off
|
||||||
--lib:PATH set the system library path
|
--lib:PATH set the path to the system.nim library
|
||||||
-c, --compileOnly compile only; do not assemble or link
|
-c, --compileOnly compile only; do not assemble or link
|
||||||
--noLinking compile but do not link
|
--noLinking compile but do not link
|
||||||
--noMain do not generate a main procedure
|
--noMain do not generate a main procedure
|
||||||
|
|
|
||||||
|
|
@ -10,21 +10,21 @@ a `base type`:idx:.
|
||||||
|
|
||||||
Use case 1: SQL strings
|
Use case 1: SQL strings
|
||||||
-----------------------
|
-----------------------
|
||||||
An SQL statement that is passed from Nimrod to an SQL database might be
|
An SQL statement that is passed from Nimrod to an SQL database might be
|
||||||
modelled as a string. However, using string templates and filling in the
|
modelled as a string. However, using string templates and filling in the
|
||||||
values is vulnerable to the famous `SQL injection attack`:idx:\:
|
values is vulnerable to the famous `SQL injection attack`:idx:\:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
proc query(db: TDbHandle, statement: TSQL) = ...
|
proc query(db: TDbHandle, statement: TSQL) = ...
|
||||||
|
|
||||||
var
|
var
|
||||||
username: string
|
username: string
|
||||||
|
|
||||||
db.query("SELECT FROM users WHERE name = '$1'" % username)
|
db.query("SELECT FROM users WHERE name = '$1'" % username)
|
||||||
# Horrible security whole, but the compiler does not mind!
|
# Horrible security hole, but the compiler does not mind!
|
||||||
|
|
||||||
This can be avoided by distinguishing strings that contain SQL from strings
|
This can be avoided by distinguishing strings that contain SQL from strings
|
||||||
that don't. Abstract types provide a means to introduce a new string type
|
that don't. Abstract types provide a means to introduce a new string type
|
||||||
``TSQL`` that is incompatible with ``string``:
|
``TSQL`` that is incompatible with ``string``:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
|
|
@ -35,26 +35,26 @@ that don't. Abstract types provide a means to introduce a new string type
|
||||||
|
|
||||||
var
|
var
|
||||||
username: string
|
username: string
|
||||||
|
|
||||||
db.query("SELECT FROM users WHERE name = '$1'" % username)
|
db.query("SELECT FROM users WHERE name = '$1'" % username)
|
||||||
# Error at compile time: `query` expects an SQL string!
|
# Error at compile time: `query` expects an SQL string!
|
||||||
|
|
||||||
|
|
||||||
It is an essential property of abstract types that they **do not** imply a
|
It is an essential property of abstract types that they **do not** imply a
|
||||||
subtype relation between the abtract type and its base type. Explict type
|
subtype relation between the abtract type and its base type. Explict type
|
||||||
conversions from ``string`` to ``TSQL`` are allowed:
|
conversions from ``string`` to ``TSQL`` are allowed:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
proc properQuote(s: string): TSQL =
|
proc properQuote(s: string): TSQL =
|
||||||
# quotes a string properly for an SQL statement
|
# quotes a string properly for an SQL statement
|
||||||
...
|
...
|
||||||
|
|
||||||
proc `%` (frmt: TSQL, values: openarray[string]): TSQL =
|
proc `%` (frmt: TSQL, values: openarray[string]): TSQL =
|
||||||
# quote each argument:
|
# quote each argument:
|
||||||
var v = values.each(properQuote)
|
var v = values.each(properQuote)
|
||||||
# we need a temporary type for the type conversion :-(
|
# we need a temporary type for the type conversion :-(
|
||||||
type TStrSeq = seq[string]
|
type TStrSeq = seq[string]
|
||||||
# call strutils.`%`:
|
# call strutils.`%`:
|
||||||
result = TSQL(string(frmt) % TStrSeq(v))
|
result = TSQL(string(frmt) % TStrSeq(v))
|
||||||
|
|
||||||
db.query("SELECT FROM users WHERE name = $1".TSQL % username)
|
db.query("SELECT FROM users WHERE name = $1".TSQL % username)
|
||||||
|
|
@ -68,43 +68,43 @@ for nice looking ``TSQL`` string literals.
|
||||||
Use case 2: Money
|
Use case 2: Money
|
||||||
-----------------
|
-----------------
|
||||||
Different currencies should not be mixed in monetary calculations. Abstract
|
Different currencies should not be mixed in monetary calculations. Abstract
|
||||||
types are a perfect tool to model different currencies:
|
types are a perfect tool to model different currencies:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
type
|
type
|
||||||
TDollar = abstract int
|
TDollar = abstract int
|
||||||
TEuro = abstract int
|
TEuro = abstract int
|
||||||
|
|
||||||
var
|
var
|
||||||
d: TDollar
|
d: TDollar
|
||||||
e: TEuro
|
e: TEuro
|
||||||
|
|
||||||
echo d + 12
|
echo d + 12
|
||||||
# Error: cannot add a number with no unit with a ``TDollar``
|
# Error: cannot add a number with no unit with a ``TDollar``
|
||||||
|
|
||||||
Unfortunetaly, ``d + 12.TDollar`` is not allowed either,
|
Unfortunetaly, ``d + 12.TDollar`` is not allowed either,
|
||||||
because ``+`` is defined for ``int`` (among others), not for ``TDollar``. So
|
because ``+`` is defined for ``int`` (among others), not for ``TDollar``. So
|
||||||
we define our own ``+`` for dollars:
|
we define our own ``+`` for dollars:
|
||||||
|
|
||||||
.. code-block::
|
.. code-block::
|
||||||
proc `+` (x, y: TDollar): TDollar =
|
proc `+` (x, y: TDollar): TDollar =
|
||||||
result = TDollar(int(x) + int(y))
|
result = TDollar(int(x) + int(y))
|
||||||
|
|
||||||
It does not make sense to multiply a dollar with a dollar, but with a
|
It does not make sense to multiply a dollar with a dollar, but with a
|
||||||
number without unit; and the same holds for division:
|
number without unit; and the same holds for division:
|
||||||
|
|
||||||
.. code-block::
|
.. code-block::
|
||||||
proc `*` (x: TDollar, y: int): TDollar =
|
proc `*` (x: TDollar, y: int): TDollar =
|
||||||
result = TDollar(int(x) * y)
|
result = TDollar(int(x) * y)
|
||||||
|
|
||||||
proc `*` (x: int, y: TDollar): TDollar =
|
proc `*` (x: int, y: TDollar): TDollar =
|
||||||
result = TDollar(x * int(y))
|
result = TDollar(x * int(y))
|
||||||
|
|
||||||
proc `div` ...
|
proc `div` ...
|
||||||
|
|
||||||
This quickly gets tedious. The implementations are trivial and the compiler
|
This quickly gets tedious. The implementations are trivial and the compiler
|
||||||
should not generate all this code only to optimize it away later - after all
|
should not generate all this code only to optimize it away later - after all
|
||||||
``+`` for dollars should produce the same binary code as ``+`` for ints.
|
``+`` for dollars should produce the same binary code as ``+`` for ints.
|
||||||
The pragma ``borrow`` has been designed to solve this problem; in principle
|
The pragma ``borrow`` has been designed to solve this problem; in principle
|
||||||
it generates the trivial implementation for us:
|
it generates the trivial implementation for us:
|
||||||
|
|
||||||
|
|
@ -113,40 +113,40 @@ it generates the trivial implementation for us:
|
||||||
proc `*` (x: int, y: TDollar): TDollar {.borrow.}
|
proc `*` (x: int, y: TDollar): TDollar {.borrow.}
|
||||||
proc `div` (x: TDollar, y: int): TDollar {.borrow.}
|
proc `div` (x: TDollar, y: int): TDollar {.borrow.}
|
||||||
|
|
||||||
The ``borrow`` pragma makes the compiler use the same implementation as
|
The ``borrow`` pragma makes the compiler to use the same implementation as
|
||||||
the proc that deals with the abstract type's base type, so no code is
|
the proc that deals with the abstract type's base type, so no code is
|
||||||
generated.
|
generated.
|
||||||
|
|
||||||
But it seems we still have to repeat all this boilerplate code for
|
But it seems we still have to repeat all this boilerplate code for
|
||||||
the ``TEuro`` currency. Fortunately, Nimrod has a template mechanism:
|
the ``TEuro`` currency. Fortunately, Nimrod has a template mechanism:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
template Additive(typ: typeDesc): stmt =
|
template Additive(typ: typeDesc): stmt =
|
||||||
proc `+` *(x, y: typ): typ {.borrow.}
|
proc `+` *(x, y: typ): typ {.borrow.}
|
||||||
proc `-` *(x, y: typ): typ {.borrow.}
|
proc `-` *(x, y: typ): typ {.borrow.}
|
||||||
|
|
||||||
# unary operators:
|
# unary operators:
|
||||||
proc `+` *(x: typ): typ {.borrow.}
|
proc `+` *(x: typ): typ {.borrow.}
|
||||||
proc `-` *(x: typ): typ {.borrow.}
|
proc `-` *(x: typ): typ {.borrow.}
|
||||||
|
|
||||||
template Multiplicative(typ, base: typeDesc): stmt =
|
template Multiplicative(typ, base: typeDesc): stmt =
|
||||||
proc `*` *(x: typ, y: base): typ {.borrow.}
|
proc `*` *(x: typ, y: base): typ {.borrow.}
|
||||||
proc `*` *(x: base, y: typ): typ {.borrow.}
|
proc `*` *(x: base, y: typ): typ {.borrow.}
|
||||||
proc `div` *(x: typ, y: base): typ {.borrow.}
|
proc `div` *(x: typ, y: base): typ {.borrow.}
|
||||||
proc `mod` *(x: typ, y: base): typ {.borrow.}
|
proc `mod` *(x: typ, y: base): typ {.borrow.}
|
||||||
|
|
||||||
template Comparable(typ: typeDesc): stmt =
|
template Comparable(typ: typeDesc): stmt =
|
||||||
proc `<` * (x, y: typ): bool {.borrow.}
|
proc `<` * (x, y: typ): bool {.borrow.}
|
||||||
proc `<=` * (x, y: typ): bool {.borrow.}
|
proc `<=` * (x, y: typ): bool {.borrow.}
|
||||||
proc `==` * (x, y: typ): bool {.borrow.}
|
proc `==` * (x, y: typ): bool {.borrow.}
|
||||||
|
|
||||||
template DefineCurrency(typ, base: expr): stmt =
|
template DefineCurrency(typ, base: expr): stmt =
|
||||||
type
|
type
|
||||||
typ* = abstract base
|
typ* = abstract base
|
||||||
Additive(typ)
|
Additive(typ)
|
||||||
Multiplicative(typ, base)
|
Multiplicative(typ, base)
|
||||||
Comparable(typ)
|
Comparable(typ)
|
||||||
|
|
||||||
DefineCurrency(TDollar, int)
|
DefineCurrency(TDollar, int)
|
||||||
DefineCurrency(TEuro, int)
|
DefineCurrency(TEuro, int)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ explicit like in Haskell?
|
||||||
The idea is that side effects and partial evaluation belong together:
|
The idea is that side effects and partial evaluation belong together:
|
||||||
Iff a proc is side effect free and all its argument are evaluable at
|
Iff a proc is side effect free and all its argument are evaluable at
|
||||||
compile time, it can be evaluated by the compiler. However, really
|
compile time, it can be evaluated by the compiler. However, really
|
||||||
difficult is the ``newString`` proc: If it is simply wrapped, it
|
difficult is the ``newString`` proc: If it is simply wrapped, it
|
||||||
should not be evaluated at compile time! On other occasions it can
|
should not be evaluated at compile time! On other occasions it can
|
||||||
and should be evaluted:
|
and should be evaluted:
|
||||||
|
|
||||||
|
|
@ -20,22 +20,22 @@ and should be evaluted:
|
||||||
result[i] = toUpper(s[i])
|
result[i] = toUpper(s[i])
|
||||||
|
|
||||||
No, it really can always be evaluated. The code generator should transform
|
No, it really can always be evaluated. The code generator should transform
|
||||||
``s = "\0\0\0..."`` back into ``s = newString(...)``.
|
``s = "\0\0\0..."`` back into ``s = newString(...)``.
|
||||||
|
|
||||||
|
|
||||||
``new`` cannot be evaluated at compile time either.
|
``new`` cannot be evaluated at compile time either.
|
||||||
|
|
||||||
|
|
||||||
Raise statement
|
Raise statement
|
||||||
===============
|
===============
|
||||||
|
|
||||||
It is impractical to consider ``raise`` a statement with side effects.
|
It is impractical to consider ``raise`` as a statement with side effects.
|
||||||
|
|
||||||
|
|
||||||
Solution
|
Solution
|
||||||
========
|
========
|
||||||
|
|
||||||
Being side effect free does not suffice for compile time evaluation. However,
|
Being side effect free does not suffice for compile time evaluation. However,
|
||||||
the evaluator can attempt to evaluate at compile time.
|
the evaluator can attempt to evaluate at compile time.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ available for the debugger.
|
||||||
|
|
||||||
If you start your program the debugger will immediately show
|
If you start your program the debugger will immediately show
|
||||||
a prompt on the console. You can now enter a command. The next sections
|
a prompt on the console. You can now enter a command. The next sections
|
||||||
deal with the possible commands. As usual for Nimrod for all commands
|
deal with the possible commands. As usual in Nimrod in all commands
|
||||||
underscores and case do not matter. Optional components of a command
|
underscores and case do not matter. Optional components of a command
|
||||||
are listed in brackets ``[...]`` here.
|
are listed in brackets ``[...]`` here.
|
||||||
|
|
||||||
|
|
|
||||||
78
doc/lib.txt
78
doc/lib.txt
|
|
@ -12,7 +12,7 @@ Nimrod Standard Library
|
||||||
Though the Nimrod Standard Library is still evolving, it is already quite
|
Though the Nimrod Standard Library is still evolving, it is already quite
|
||||||
usable. It is divided into *pure libraries*, *impure libraries* and *wrappers*.
|
usable. It is divided into *pure libraries*, *impure libraries* and *wrappers*.
|
||||||
|
|
||||||
Pure libraries do not depend on any external ``*.dll`` or ``lib*.so`` binary
|
Pure libraries do not depend on any external ``*.dll`` or ``lib*.so`` binary
|
||||||
while impure libraries do. A wrapper is an impure library that is a very
|
while impure libraries do. A wrapper is an impure library that is a very
|
||||||
low-level interface to a C library.
|
low-level interface to a C library.
|
||||||
|
|
||||||
|
|
@ -31,7 +31,7 @@ Core
|
||||||
implicitly by the compiler. Do not import it directly. It relies on compiler
|
implicitly by the compiler. Do not import it directly. It relies on compiler
|
||||||
magic to work.
|
magic to work.
|
||||||
|
|
||||||
* `macros <macros.html>`_
|
* `macros <macros.html>`_
|
||||||
Contains the AST API and documentation of Nimrod for writing macros.
|
Contains the AST API and documentation of Nimrod for writing macros.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -39,8 +39,8 @@ String handling
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
* `strutils <strutils.html>`_
|
* `strutils <strutils.html>`_
|
||||||
This module contains common string handling operations like converting a
|
This module contains common string handling operations like changing
|
||||||
string into uppercase, splitting a string into substrings, searching for
|
case of a string, splitting a string into substrings, searching for
|
||||||
substrings, replacing substrings.
|
substrings, replacing substrings.
|
||||||
|
|
||||||
* `parseutils <parseutils.html>`_
|
* `parseutils <parseutils.html>`_
|
||||||
|
|
@ -52,7 +52,7 @@ String handling
|
||||||
style-insensitive mode. An efficient string substitution operator ``%``
|
style-insensitive mode. An efficient string substitution operator ``%``
|
||||||
for the string table is also provided.
|
for the string table is also provided.
|
||||||
|
|
||||||
* `unicode <unicode.html>`_
|
* `unicode <unicode.html>`_
|
||||||
This module provides support to handle the Unicode UTF-8 encoding.
|
This module provides support to handle the Unicode UTF-8 encoding.
|
||||||
|
|
||||||
* `re <re.html>`_
|
* `re <re.html>`_
|
||||||
|
|
@ -67,11 +67,11 @@ String handling
|
||||||
Ropes can represent very long strings efficiently; especially concatenation
|
Ropes can represent very long strings efficiently; especially concatenation
|
||||||
is done in O(1) instead of O(n).
|
is done in O(1) instead of O(n).
|
||||||
|
|
||||||
* `unidecode <unidecode.html>`_
|
* `unidecode <unidecode.html>`_
|
||||||
This module provides Unicode to ASCII transliterations:
|
This module provides Unicode to ASCII transliterations:
|
||||||
It finds the sequence of ASCII characters that is the closest approximation
|
It finds the sequence of ASCII characters that is the closest approximation
|
||||||
to the Unicode string.
|
to the Unicode string.
|
||||||
|
|
||||||
|
|
||||||
Generic Operating System Services
|
Generic Operating System Services
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
@ -97,8 +97,8 @@ Generic Operating System Services
|
||||||
may provide other implementations for this standard stream interface.
|
may provide other implementations for this standard stream interface.
|
||||||
|
|
||||||
* `terminal <terminal.html>`_
|
* `terminal <terminal.html>`_
|
||||||
This module contains a few procedures to control the *terminal*
|
This module contains a few procedures to control the *terminal*
|
||||||
(also called *console*). The implementation simply uses ANSI escape
|
(also called *console*). The implementation simply uses ANSI escape
|
||||||
sequences and does not depend on any other module.
|
sequences and does not depend on any other module.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -117,20 +117,20 @@ Internet Protocols and Support
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
* `cgi <cgi.html>`_
|
* `cgi <cgi.html>`_
|
||||||
This module implements helpers for CGI applictions.
|
This module implements helpers for CGI applictions.
|
||||||
|
|
||||||
* `sockets <sockets.html>`_
|
* `sockets <sockets.html>`_
|
||||||
This module implements a simple portable type-safe sockets layer.
|
This module implements a simple portable type-safe sockets layer.
|
||||||
|
|
||||||
* `browsers <browsers.html>`_
|
* `browsers <browsers.html>`_
|
||||||
This module implements procs for opening URLs with the user's default
|
This module implements procs for opening URLs with the user's default
|
||||||
browser.
|
browser.
|
||||||
|
|
||||||
* `httpserver <httpserver.html>`_
|
* `httpserver <httpserver.html>`_
|
||||||
This module implements a simple HTTP server.
|
This module implements a simple HTTP server.
|
||||||
|
|
||||||
* `httpclient <httpclient.html>`_
|
* `httpclient <httpclient.html>`_
|
||||||
This module implements a simple HTTP client.
|
This module implements a simple HTTP client.
|
||||||
|
|
||||||
|
|
||||||
Parsers
|
Parsers
|
||||||
|
|
@ -149,14 +149,14 @@ Parsers
|
||||||
as in the Nimrod programming language.
|
as in the Nimrod programming language.
|
||||||
|
|
||||||
* `parsexml <parsexml.html>`_
|
* `parsexml <parsexml.html>`_
|
||||||
The ``parsexml`` module implements a simple high performance XML/HTML parser.
|
The ``parsexml`` module implements a simple high performance XML/HTML parser.
|
||||||
The only encoding that is supported is UTF-8. The parser has been designed
|
The only encoding that is supported is UTF-8. The parser has been designed
|
||||||
to be somewhat error correcting, so that even some "wild HTML" found on the
|
to be somewhat error correcting, so that even some "wild HTML" found on the
|
||||||
web can be parsed with it.
|
Web can be parsed with it.
|
||||||
|
|
||||||
* `parsecsv <parsecsv.html>`_
|
* `parsecsv <parsecsv.html>`_
|
||||||
The ``parsecsv`` module implements a simple high performance CSV parser.
|
The ``parsecsv`` module implements a simple high performance CSV parser.
|
||||||
|
|
||||||
* `parsesql <parsesql.html>`_
|
* `parsesql <parsesql.html>`_
|
||||||
The ``parsesql`` module implements a simple high performance SQL parser.
|
The ``parsesql`` module implements a simple high performance SQL parser.
|
||||||
|
|
||||||
|
|
@ -168,20 +168,20 @@ Parsers
|
||||||
XML Processing
|
XML Processing
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
* `xmldom <xmldom.html>`_
|
* `xmldom <xmldom.html>`_
|
||||||
This module implements the XML DOM Level 2.
|
This module implements the XML DOM Level 2.
|
||||||
|
|
||||||
* `xmldomparser <xmldomparser.html>`_
|
* `xmldomparser <xmldomparser.html>`_
|
||||||
This module parses an XML Document into a XML DOM Document representation.
|
This module parses an XML Document into a XML DOM Document representation.
|
||||||
|
|
||||||
* `xmltree <xmltree.html>`_
|
* `xmltree <xmltree.html>`_
|
||||||
A simple XML tree. More efficient and simpler than the DOM. It also
|
A simple XML tree. More efficient and simpler than the DOM. It also
|
||||||
contains a macro for XML/HTML code generation.
|
contains a macro for XML/HTML code generation.
|
||||||
|
|
||||||
* `xmlparser <xmlparser.html>`_
|
* `xmlparser <xmlparser.html>`_
|
||||||
This module parses an XML document and creates its XML tree representation.
|
This module parses an XML document and creates its XML tree representation.
|
||||||
|
|
||||||
* `htmlparser <htmlparser.html>`_
|
* `htmlparser <htmlparser.html>`_
|
||||||
This module parses an HTML document and creates its XML tree representation.
|
This module parses an HTML document and creates its XML tree representation.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -199,8 +199,8 @@ Cryptography and Hashing
|
||||||
Multimedia support
|
Multimedia support
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
* `colors <colors.html>`_
|
* `colors <colors.html>`_
|
||||||
This module implements color handling for Nimrod. It is used by
|
This module implements color handling for Nimrod. It is used by
|
||||||
the ``graphics`` module.
|
the ``graphics`` module.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -211,7 +211,7 @@ Impure libraries
|
||||||
* `graphics <graphics.html>`_
|
* `graphics <graphics.html>`_
|
||||||
This module implements graphical output for Nimrod; the current
|
This module implements graphical output for Nimrod; the current
|
||||||
implementation uses SDL but the interface is meant to support multiple
|
implementation uses SDL but the interface is meant to support multiple
|
||||||
backends some day.
|
backends some day.
|
||||||
|
|
||||||
* `dialogs <dialogs.html>`_
|
* `dialogs <dialogs.html>`_
|
||||||
This module implements portable dialogs for Nimrod; the implementation
|
This module implements portable dialogs for Nimrod; the implementation
|
||||||
|
|
@ -220,10 +220,10 @@ Impure libraries
|
||||||
|
|
||||||
* `zipfiles <zipfiles.html>`_
|
* `zipfiles <zipfiles.html>`_
|
||||||
This module implements a zip archive creator/reader/modifier.
|
This module implements a zip archive creator/reader/modifier.
|
||||||
|
|
||||||
* `web <web.html>`_
|
* `web <web.html>`_
|
||||||
This module contains simple high-level procedures for dealing with the
|
This module contains simple high-level procedures for dealing with the
|
||||||
web like loading the contents of a web page from an URL.
|
Web like loading the contents of a Web page from an URL.
|
||||||
|
|
||||||
|
|
||||||
Database support
|
Database support
|
||||||
|
|
@ -232,13 +232,13 @@ Database support
|
||||||
* `db_postgres <db_postgres.html>`_
|
* `db_postgres <db_postgres.html>`_
|
||||||
A higher level PostgreSQL database wrapper. The same interface is implemented
|
A higher level PostgreSQL database wrapper. The same interface is implemented
|
||||||
for other databases too.
|
for other databases too.
|
||||||
|
|
||||||
* `db_mysql <db_mysql.html>`_
|
* `db_mysql <db_mysql.html>`_
|
||||||
A higher level mySQL database wrapper. The same interface is implemented
|
A higher level MySQL database wrapper. The same interface is implemented
|
||||||
for other databases too.
|
for other databases too.
|
||||||
|
|
||||||
* `db_sqlite <db_sqlite.html>`_
|
* `db_sqlite <db_sqlite.html>`_
|
||||||
A higher level mySQL database wrapper. The same interface is implemented
|
A higher level SQLite database wrapper. The same interface is implemented
|
||||||
for other databases too.
|
for other databases too.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -255,7 +255,7 @@ not contained in the distribution. You can then find them on the website.
|
||||||
Contains a wrapper for the Win32 API.
|
Contains a wrapper for the Win32 API.
|
||||||
* `mysql <mysql.html>`_
|
* `mysql <mysql.html>`_
|
||||||
Contains a wrapper for the mySQL API.
|
Contains a wrapper for the mySQL API.
|
||||||
* `sqlite3 <sqlite3.html>`_
|
* `sqlite3 <sqlite3.html>`_
|
||||||
Contains a wrapper for SQLite 3 API.
|
Contains a wrapper for SQLite 3 API.
|
||||||
* `libcurl <libcurl.html>`_
|
* `libcurl <libcurl.html>`_
|
||||||
Contains a wrapper for the libcurl library.
|
Contains a wrapper for the libcurl library.
|
||||||
|
|
@ -317,14 +317,14 @@ not contained in the distribution. You can then find them on the website.
|
||||||
Part of the wrapper for Lua.
|
Part of the wrapper for Lua.
|
||||||
* `lauxlib <lauxlib.html>`_
|
* `lauxlib <lauxlib.html>`_
|
||||||
Part of the wrapper for Lua.
|
Part of the wrapper for Lua.
|
||||||
* `tcl <tcl.html>`_
|
* `tcl <tcl.html>`_
|
||||||
Wrapper for the TCL programming language.
|
Wrapper for the TCL programming language.
|
||||||
* `python <python.html>`_
|
* `python <python.html>`_
|
||||||
Wrapper for the Python programming language.
|
Wrapper for the Python programming language.
|
||||||
* `odbcsql <odbcsql.html>`_
|
* `odbcsql <odbcsql.html>`_
|
||||||
interface to the ODBC driver.
|
interface to the ODBC driver.
|
||||||
* `zlib <zlib.html>`_
|
* `zlib <zlib.html>`_
|
||||||
Wrapper for the zlib library.
|
Wrapper for the zlib library.
|
||||||
* `sdl <sdl.html>`_
|
* `sdl <sdl.html>`_
|
||||||
Part of the wrapper for SDL.
|
Part of the wrapper for SDL.
|
||||||
* `sdl_gfx <sdl_gfx.html>`_
|
* `sdl_gfx <sdl_gfx.html>`_
|
||||||
|
|
@ -379,7 +379,7 @@ not contained in the distribution. You can then find them on the website.
|
||||||
Part of the wrapper for X11.
|
Part of the wrapper for X11.
|
||||||
* `libzip <libzip.html>`_
|
* `libzip <libzip.html>`_
|
||||||
Interface to the `lib zip <http://www.nih.at/libzip/index.html>`_ library by
|
Interface to the `lib zip <http://www.nih.at/libzip/index.html>`_ library by
|
||||||
Dieter Baron and Thomas Klausner.
|
Dieter Baron and Thomas Klausner.
|
||||||
* `iup <iup.html>`_
|
* `iup <iup.html>`_
|
||||||
Wrapper of the IUP GUI library.
|
Wrapper of the IUP GUI library.
|
||||||
|
|
||||||
|
|
|
||||||
5529
doc/manual.txt
5529
doc/manual.txt
File diff suppressed because it is too large
Load diff
478
doc/nimrodc.txt
478
doc/nimrodc.txt
|
|
@ -1,239 +1,239 @@
|
||||||
===================================
|
===================================
|
||||||
Nimrod Compiler User Guide
|
Nimrod Compiler User Guide
|
||||||
===================================
|
===================================
|
||||||
|
|
||||||
:Author: Andreas Rumpf
|
:Author: Andreas Rumpf
|
||||||
:Version: |nimrodversion|
|
:Version: |nimrodversion|
|
||||||
|
|
||||||
.. contents::
|
.. contents::
|
||||||
|
|
||||||
"Look at you, hacker. A pathetic creature of meat and bone, panting and
|
"Look at you, hacker. A pathetic creature of meat and bone, panting and
|
||||||
sweating as you run through my corridors. How can you challenge a perfect,
|
sweating as you run through my corridors. How can you challenge a perfect,
|
||||||
immortal machine?"
|
immortal machine?"
|
||||||
|
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
============
|
============
|
||||||
|
|
||||||
This document describes the usage of the *Nimrod compiler*
|
This document describes the usage of the *Nimrod compiler*
|
||||||
on the different supported platforms. It is not a definition of the Nimrod
|
on the different supported platforms. It is not a definition of the Nimrod
|
||||||
programming language (therefore is the `manual <manual>`_).
|
programming language (therefore is the `manual <manual>`_).
|
||||||
|
|
||||||
Nimrod is free software; it is licensed under the
|
Nimrod is free software; it is licensed under the
|
||||||
`GNU General Public License <gpl.html>`_.
|
`GNU General Public License <gpl.html>`_.
|
||||||
|
|
||||||
|
|
||||||
Compiler Usage
|
Compiler Usage
|
||||||
==============
|
==============
|
||||||
|
|
||||||
Command line switches
|
Command line switches
|
||||||
---------------------
|
---------------------
|
||||||
Basis command line switches are:
|
Basis command line switches are:
|
||||||
|
|
||||||
.. include:: ../data/basicopt.txt
|
.. include:: ../data/basicopt.txt
|
||||||
|
|
||||||
Advanced command line switches are:
|
Advanced command line switches are:
|
||||||
|
|
||||||
.. include:: ../data/advopt.txt
|
.. include:: ../data/advopt.txt
|
||||||
|
|
||||||
|
|
||||||
Configuration file
|
Configuration file
|
||||||
------------------
|
------------------
|
||||||
The default configuration file is ``nimrod.cfg``. The ``nimrod`` executable
|
The default configuration file is ``nimrod.cfg``. The ``nimrod`` executable
|
||||||
looks for it in the following directories (in this order):
|
looks for it in the following directories (in this order):
|
||||||
|
|
||||||
1. ``/home/$user/.config/nimrod.cfg`` (UNIX) or ``%APPDATA%/nimrod.cfg`` (Windows)
|
1. ``/home/$user/.config/nimrod.cfg`` (UNIX) or ``%APPDATA%/nimrod.cfg`` (Windows)
|
||||||
2. ``$nimrod/config/nimrod.cfg`` (UNIX, Windows)
|
2. ``$nimrod/config/nimrod.cfg`` (UNIX), ``%NIMROD%/config/nimrod.cfg`` (Windows)
|
||||||
3. ``/etc/nimrod.cfg`` (UNIX)
|
3. ``/etc/nimrod.cfg`` (UNIX)
|
||||||
|
|
||||||
The search stops as soon as a configuration file has been found. The reading
|
The search stops as soon as a configuration file has been found. The reading
|
||||||
of ``nimrod.cfg`` can be suppressed by the ``--skipCfg`` command line option.
|
of ``nimrod.cfg`` can be suppressed by the ``--skipCfg`` command line option.
|
||||||
|
|
||||||
**Note:** The *project file name* is the name of the ``.nim`` file that is
|
**Note:** The *project file name* is the name of the ``.nim`` file that is
|
||||||
passed as a command line argument to the compiler.
|
passed as a command line argument to the compiler.
|
||||||
|
|
||||||
Configuration settings can be overwritten in a project specific
|
Configuration settings can be overwritten individually in a project specific
|
||||||
configuration file that is read automatically. This specific file has to
|
configuration file that is read automatically. This specific file has to
|
||||||
be in the same directory as the project and be of the same name, except
|
be in the same directory as the project and be of the same name, except
|
||||||
that its extension should be ``.cfg``.
|
that its extension should be ``.cfg``.
|
||||||
|
|
||||||
Command line settings have priority over configuration file settings.
|
Command line settings have priority over configuration file settings.
|
||||||
|
|
||||||
|
|
||||||
Generated C code directory
|
Generated C code directory
|
||||||
--------------------------
|
--------------------------
|
||||||
The generated files that Nimrod produces all go into a subdirectory called
|
The generated files that Nimrod produces all go into a subdirectory called
|
||||||
``nimcache`` in your project directory. This makes it easy to delete all
|
``nimcache`` in your project directory. This makes it easy to delete all
|
||||||
generated files.
|
generated files.
|
||||||
|
|
||||||
However, the generated C code is not platform independant. C code generated for
|
However, the generated C code is not platform independant. C code generated for
|
||||||
Linux does not compile on Windows, for instance. The comment on top of the
|
Linux does not compile on Windows, for instance. The comment on top of the
|
||||||
C file lists the OS, CPU and CC the file has been compiled for.
|
C file lists the OS, CPU and CC the file has been compiled for.
|
||||||
|
|
||||||
|
|
||||||
Additional Features
|
Additional Features
|
||||||
===================
|
===================
|
||||||
|
|
||||||
This section describes Nimrod's additional features that are not listed in the
|
This section describes Nimrod's additional features that are not listed in the
|
||||||
Nimrod manual. Some of the features here only make sense for the C code
|
Nimrod manual. Some of the features here only make sense for the C code
|
||||||
generator and are subject to change.
|
generator and are subject to change.
|
||||||
|
|
||||||
|
|
||||||
NoDecl pragma
|
NoDecl pragma
|
||||||
-------------
|
-------------
|
||||||
The `noDecl`:idx: pragma can be applied to almost any symbol (variable, proc,
|
The `noDecl`:idx: pragma can be applied to almost any symbol (variable, proc,
|
||||||
type, etc.) and is sometimes useful for interoperability with C:
|
type, etc.) and is sometimes useful for interoperability with C:
|
||||||
It tells Nimrod that it should not generate a declaration for the symbol in
|
It tells Nimrod that it should not generate a declaration for the symbol in
|
||||||
the C code. For example:
|
the C code. For example:
|
||||||
|
|
||||||
.. code-block:: Nimrod
|
.. code-block:: Nimrod
|
||||||
var
|
var
|
||||||
EACCES {.importc, noDecl.}: cint # pretend EACCES was a variable, as
|
EACCES {.importc, noDecl.}: cint # pretend EACCES was a variable, as
|
||||||
# Nimrod does not know its value
|
# Nimrod does not know its value
|
||||||
|
|
||||||
However, the ``header`` pragma is often the better alternative.
|
However, the ``header`` pragma is often the better alternative.
|
||||||
|
|
||||||
**Note**: This will not work for the LLVM backend.
|
**Note**: This will not work for the LLVM backend.
|
||||||
|
|
||||||
|
|
||||||
Header pragma
|
Header pragma
|
||||||
-------------
|
-------------
|
||||||
The `header`:idx: pragma is very similar to the ``noDecl`` pragma: It can be
|
The `header`:idx: pragma is very similar to the ``noDecl`` pragma: It can be
|
||||||
applied to almost any symbol and specifies that it should not be declared
|
applied to almost any symbol and specifies that it should not be declared
|
||||||
and instead the generated code should contain an ``#include``:
|
and instead the generated code should contain an ``#include``:
|
||||||
|
|
||||||
.. code-block:: Nimrod
|
.. code-block:: Nimrod
|
||||||
type
|
type
|
||||||
PFile {.importc: "FILE*", header: "<stdio.h>".} = distinct pointer
|
PFile {.importc: "FILE*", header: "<stdio.h>".} = distinct pointer
|
||||||
# import C's FILE* type; Nimrod will treat it as a new pointer type
|
# import C's FILE* type; Nimrod will treat it as a new pointer type
|
||||||
|
|
||||||
The ``header`` pragma always expects a string constant. The string contant
|
The ``header`` pragma always expects a string constant. The string contant
|
||||||
contains the header file: As usual for C, a system header file is enclosed
|
contains the header file: As usual for C, a system header file is enclosed
|
||||||
in angle brackets: ``<>``. If no angle brackets are given, Nimrod
|
in angle brackets: ``<>``. If no angle brackets are given, Nimrod
|
||||||
encloses the header file in ``""`` in the generated C code.
|
encloses the header file in ``""`` in the generated C code.
|
||||||
|
|
||||||
**Note**: This will not work for the LLVM backend.
|
**Note**: This will not work for the LLVM backend.
|
||||||
|
|
||||||
|
|
||||||
LineDir option
|
LineDir option
|
||||||
--------------
|
--------------
|
||||||
The `lineDir`:idx: option can be turned on or off. If turned on the
|
The `lineDir`:idx: option can be turned on or off. If turned on the
|
||||||
generated C code contains ``#line`` directives. This may be helpful for
|
generated C code contains ``#line`` directives. This may be helpful for
|
||||||
debugging with GDB.
|
debugging with GDB.
|
||||||
|
|
||||||
|
|
||||||
StackTrace option
|
StackTrace option
|
||||||
-----------------
|
-----------------
|
||||||
If the `stackTrace`:idx: option is turned on, the generated C contains code to
|
If the `stackTrace`:idx: option is turned on, the generated C contains code to
|
||||||
ensure that proper stack traces are given if the program crashes or an
|
ensure that proper stack traces are given if the program crashes or an
|
||||||
uncaught exception is raised.
|
uncaught exception is raised.
|
||||||
|
|
||||||
|
|
||||||
LineTrace option
|
LineTrace option
|
||||||
----------------
|
----------------
|
||||||
The `lineTrace`:idx: option implies the ``stackTrace`` option. If turned on,
|
The `lineTrace`:idx: option implies the ``stackTrace`` option. If turned on,
|
||||||
the generated C contains code to ensure that proper stack traces with line
|
the generated C contains code to ensure that proper stack traces with line
|
||||||
number information are given if the program crashes or an uncaught exception
|
number information are given if the program crashes or an uncaught exception
|
||||||
is raised.
|
is raised.
|
||||||
|
|
||||||
Debugger option
|
Debugger option
|
||||||
---------------
|
---------------
|
||||||
The `debugger`:idx: option enables or disables the *Embedded Nimrod Debugger*.
|
The `debugger`:idx: option enables or disables the *Embedded Nimrod Debugger*.
|
||||||
See the documentation of endb_ for further information.
|
See the documentation of endb_ for further information.
|
||||||
|
|
||||||
|
|
||||||
Breakpoint pragma
|
Breakpoint pragma
|
||||||
-----------------
|
-----------------
|
||||||
The *breakpoint* pragma was specially added for the sake of debugging with
|
The *breakpoint* pragma was specially added for the sake of debugging with
|
||||||
ENDB. See the documentation of `endb <endb.html>`_ for further information.
|
ENDB. See the documentation of `endb <endb.html>`_ for further information.
|
||||||
|
|
||||||
|
|
||||||
Volatile pragma
|
Volatile pragma
|
||||||
---------------
|
---------------
|
||||||
The `volatile`:idx: pragma is for variables only. It declares the variable as
|
The `volatile`:idx: pragma is for variables only. It declares the variable as
|
||||||
``volatile``, whatever that means in C/C++.
|
``volatile``, whatever that means in C/C++.
|
||||||
|
|
||||||
**Note**: This pragma will not exist for the LLVM backend.
|
**Note**: This pragma will not exist for the LLVM backend.
|
||||||
|
|
||||||
|
|
||||||
Debugging with Nimrod
|
Debugging with Nimrod
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
Nimrod comes with its own *Embedded Nimrod Debugger*. See
|
Nimrod comes with its own *Embedded Nimrod Debugger*. See
|
||||||
the documentation of endb_ for further information.
|
the documentation of endb_ for further information.
|
||||||
|
|
||||||
|
|
||||||
Optimizing for Nimrod
|
Optimizing for Nimrod
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
Nimrod has no separate optimizer, but the C code that is produced is very
|
Nimrod has no separate optimizer, but the C code that is produced is very
|
||||||
efficient. Most C compilers have excellent optimizers, so usually it is
|
efficient. Most C compilers have excellent optimizers, so usually it is
|
||||||
not needed to optimize one's code. Nimrod has been designed to encourage
|
not needed to optimize one's code. Nimrod has been designed to encourage
|
||||||
efficient code: The most readable code in Nimrod is often the most efficient
|
efficient code: The most readable code in Nimrod is often the most efficient
|
||||||
too.
|
too.
|
||||||
|
|
||||||
However, sometimes one has to optimize. Do it in the following order:
|
However, sometimes one has to optimize. Do it in the following order:
|
||||||
|
|
||||||
1. switch off the embedded debugger (it is **slow**!)
|
1. switch off the embedded debugger (it is **slow**!)
|
||||||
2. turn on the optimizer and turn off runtime checks
|
2. turn on the optimizer and turn off runtime checks
|
||||||
3. profile your code to find where the bottlenecks are
|
3. profile your code to find where the bottlenecks are
|
||||||
4. try to find a better algorithm
|
4. try to find a better algorithm
|
||||||
5. do low-level optimizations
|
5. do low-level optimizations
|
||||||
|
|
||||||
This section can only help you with the last item.
|
This section can only help you with the last item.
|
||||||
|
|
||||||
|
|
||||||
Optimizing string handling
|
Optimizing string handling
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
String assignments are sometimes expensive in Nimrod: They are required to
|
String assignments are sometimes expensive in Nimrod: They are required to
|
||||||
copy the whole string. However, the compiler is often smart enough to not copy
|
copy the whole string. However, the compiler is often smart enough to not copy
|
||||||
strings. Due to the argument passing semantics, strings are never copied when
|
strings. Due to the argument passing semantics, strings are never copied when
|
||||||
passed to subroutines. The compiler does not copy strings that are a result from
|
passed to subroutines. The compiler does not copy strings that are a result from
|
||||||
a procedure call, because the callee returns a new string anyway.
|
a procedure call, because the callee returns a new string anyway.
|
||||||
Thus it is efficient to do:
|
Thus it is efficient to do:
|
||||||
|
|
||||||
.. code-block:: Nimrod
|
.. code-block:: Nimrod
|
||||||
var s = procA() # assignment will not copy the string; procA allocates a new
|
var s = procA() # assignment will not copy the string; procA allocates a new
|
||||||
# string already
|
# string already
|
||||||
|
|
||||||
However it is not efficient to do:
|
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
|
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
|
if several different string constants are used. This is likely to be more
|
||||||
efficient than any hand-coded scheme.
|
efficient than any hand-coded scheme.
|
||||||
|
|
||||||
|
|
||||||
..
|
..
|
||||||
The ECMAScript code generator
|
The ECMAScript code generator
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
Note: As of version 0.7.0 the ECMAScript code generator is not maintained any
|
Note: As of version 0.7.0 the ECMAScript code generator is not maintained any
|
||||||
longer. Help if you are interested.
|
longer. Help if you are interested.
|
||||||
|
|
||||||
Note: I use the term `ECMAScript`:idx: here instead of `JavaScript`:idx:,
|
Note: I use the term `ECMAScript`:idx: here instead of `JavaScript`:idx:,
|
||||||
since it is the proper term.
|
since it is the proper term.
|
||||||
|
|
||||||
The ECMAScript code generator is experimental!
|
The ECMAScript code generator is experimental!
|
||||||
|
|
||||||
Nimrod targets ECMAScript 1.5 which is supported by any widely used browser.
|
Nimrod targets ECMAScript 1.5 which is supported by any widely used browser.
|
||||||
Since ECMAScript does not have a portable means to include another module,
|
Since ECMAScript does not have a portable means to include another module,
|
||||||
Nimrod just generates a long ``.js`` file.
|
Nimrod just generates a long ``.js`` file.
|
||||||
|
|
||||||
Features or modules that the ECMAScript platform does not support are not
|
Features or modules that the ECMAScript platform does not support are not
|
||||||
available. This includes:
|
available. This includes:
|
||||||
|
|
||||||
* manual memory management (``alloc``, etc.)
|
* manual memory management (``alloc``, etc.)
|
||||||
* casting and other unsafe operations (``cast`` operator, ``zeroMem``, etc.)
|
* casting and other unsafe operations (``cast`` operator, ``zeroMem``, etc.)
|
||||||
* file management
|
* file management
|
||||||
* most modules of the Standard library
|
* most modules of the Standard library
|
||||||
* proper 64 bit integer arithmetic
|
* proper 64 bit integer arithmetic
|
||||||
* proper unsigned integer arithmetic
|
* proper unsigned integer arithmetic
|
||||||
|
|
||||||
However, the modules `strutils`:idx:, `math`:idx:, and `times`:idx: are
|
However, the modules `strutils`:idx:, `math`:idx:, and `times`:idx: are
|
||||||
available! To access the DOM, use the `dom`:idx: module that is only
|
available! To access the DOM, use the `dom`:idx: module that is only
|
||||||
available for the ECMAScript platform.
|
available for the ECMAScript platform.
|
||||||
|
|
|
||||||
22
doc/rst.txt
22
doc/rst.txt
|
|
@ -5,16 +5,16 @@
|
||||||
:Author: Andreas Rumpf
|
:Author: Andreas Rumpf
|
||||||
:Version: |nimrodversion|
|
:Version: |nimrodversion|
|
||||||
|
|
||||||
.. contents::
|
.. contents::
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
============
|
============
|
||||||
|
|
||||||
This document describes the subset of `Docutils`_' `reStructuredText`_ as it
|
This document describes the subset of `Docutils`_' `reStructuredText`_ as it
|
||||||
has been implemented in the Nimrod compiler for generating documentation.
|
has been implemented in the Nimrod compiler for generating documentation.
|
||||||
Elements of |rst| that are not listed here have not been implemented.
|
Elements of |rst| that are not listed here have not been implemented.
|
||||||
Unfortunately, the specification of |rst| is quite vague, so Nimrod is not as
|
Unfortunately, the specification of |rst| is quite vague, so Nimrod is not as
|
||||||
compatible to the original implementation as one would like.
|
compatible to the original implementation as one would like.
|
||||||
|
|
||||||
Even though Nimrod's |rst| parser does not parse all constructs, it is pretty
|
Even though Nimrod's |rst| parser does not parse all constructs, it is pretty
|
||||||
usable. The missing features can easily be circumvented. An indication of this
|
usable. The missing features can easily be circumvented. An indication of this
|
||||||
|
|
@ -26,13 +26,13 @@ Docutils' parser.)
|
||||||
Inline elements
|
Inline elements
|
||||||
===============
|
===============
|
||||||
|
|
||||||
Ordinary text may contain *inline elements*.
|
Ordinary text may contain *inline elements*.
|
||||||
|
|
||||||
|
|
||||||
Bullet lists
|
Bullet lists
|
||||||
============
|
============
|
||||||
|
|
||||||
*Bullet lists* look like this::
|
*Bullet lists* look like this::
|
||||||
|
|
||||||
* Item 1
|
* Item 1
|
||||||
* Item 2 that
|
* Item 2 that
|
||||||
|
|
@ -60,8 +60,8 @@ Enumerated lists
|
||||||
*Enumerated lists*
|
*Enumerated lists*
|
||||||
|
|
||||||
|
|
||||||
Defintion lists
|
Definition lists
|
||||||
===============
|
================
|
||||||
|
|
||||||
Save this code to the file "greeting.nim". Now compile and run it:
|
Save this code to the file "greeting.nim". Now compile and run it:
|
||||||
|
|
||||||
|
|
@ -77,14 +77,14 @@ appending them after the filename that is to be compiled and run:
|
||||||
Tables
|
Tables
|
||||||
======
|
======
|
||||||
|
|
||||||
Nimrod only implements simple tables of the form::
|
Nimrod only implements simple tables of the form::
|
||||||
|
|
||||||
================== =============== ===================
|
================== =============== ===================
|
||||||
header 1 header 2 header n
|
header 1 header 2 header n
|
||||||
================== =============== ===================
|
================== =============== ===================
|
||||||
Cell 1 Cell 2 Cell 3
|
Cell 1 Cell 2 Cell 3
|
||||||
Cell 4 Cell 5; any Cell 6
|
Cell 4 Cell 5; any Cell 6
|
||||||
cell that is
|
cell that is
|
||||||
not in column 1
|
not in column 1
|
||||||
may span over
|
may span over
|
||||||
multiple lines
|
multiple lines
|
||||||
|
|
@ -97,7 +97,7 @@ header 1 header 2 header n
|
||||||
================== =============== ===================
|
================== =============== ===================
|
||||||
Cell 1 Cell 2 Cell 3
|
Cell 1 Cell 2 Cell 3
|
||||||
Cell 4 Cell 5; any Cell 6
|
Cell 4 Cell 5; any Cell 6
|
||||||
cell that is
|
cell that is
|
||||||
not in column 1
|
not in column 1
|
||||||
may span over
|
may span over
|
||||||
multiple lines
|
multiple lines
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
# Hallo world program
|
# Hello world program
|
||||||
|
|
||||||
echo "Hallo world!"
|
echo "Hello world!"
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ Iup.SetAttribute(box, "GAP", "10")
|
||||||
|
|
||||||
var dlg = Iup.Dialog(box)
|
var dlg = Iup.Dialog(box)
|
||||||
Iup.SetAttribute(dlg, "TITLE", "IupTabs")
|
Iup.SetAttribute(dlg, "TITLE", "IupTabs")
|
||||||
Iup.SetAttribute(dlg, "SIZE", "200x80")
|
Iup.SetAttribute(dlg, "SIZE", "200x100")
|
||||||
|
|
||||||
discard ShowXY(dlg, IUP_CENTER, IUP_CENTER)
|
discard ShowXY(dlg, IUP_CENTER, IUP_CENTER)
|
||||||
discard MainLoop()
|
discard MainLoop()
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,4 @@ import
|
||||||
#proc MessageBox(hWnd: int, lpText, lpCaption: CString, uType: uint): int
|
#proc MessageBox(hWnd: int, lpText, lpCaption: CString, uType: uint): int
|
||||||
# {stdcall, import: "MessageBox", header: "<windows.h>"}
|
# {stdcall, import: "MessageBox", header: "<windows.h>"}
|
||||||
|
|
||||||
discard MessageBox(0, "Hallo World!", "Nimrod GUI application", 0)
|
discard MessageBox(0, "Hello World!", "Nimrod GUI Application", 0)
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,10 @@ type
|
||||||
proc on_about_menu_item_activate(menuItem: PGtkMenuItem,
|
proc on_about_menu_item_activate(menuItem: PGtkMenuItem,
|
||||||
e: var TMyTextEditor) {.cdecl.} =
|
e: var TMyTextEditor) {.cdecl.} =
|
||||||
gtk_show_about_dialog(e.window,
|
gtk_show_about_dialog(e.window,
|
||||||
"comments", "A fast and leight-weight IDE for Nimrod",
|
"comments", "A fast and lightweight IDE for Nimrod",
|
||||||
"copyright", "Copyright \xc2\xa9 2008 Andreas Rumpf",
|
"copyright", "Copyright \xc2\xa9 2010 Andreas Rumpf",
|
||||||
"version", "0.1",
|
"version", "0.1",
|
||||||
"website", "http://nimrod.ethexor.com",
|
"website", "http://force7.de/nimrod/",
|
||||||
"program-name", "Nimrod IDE",
|
"program-name", "Nimrod IDE",
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
|
|
@ -70,7 +70,7 @@ proc write_file(e: var TMyTextEditor, filename: string) =
|
||||||
buffer: PGtkTextBuffer
|
buffer: PGtkTextBuffer
|
||||||
start, ende: TGtkTextIter
|
start, ende: TGtkTextIter
|
||||||
# add Saving message to status bar and ensure GUI is current
|
# add Saving message to status bar and ensure GUI is current
|
||||||
gtk_statusbar_push(e.statusbar, e.statusbar_context_id, "Saving....")
|
gtk_statusbar_push(e.statusbar, e.statusbar_context_id, "Saving...")
|
||||||
while gtk_events_pending(): gtk_main_iteration()
|
while gtk_events_pending(): gtk_main_iteration()
|
||||||
|
|
||||||
# disable text view and get contents of buffer
|
# disable text view and get contents of buffer
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ type
|
||||||
hbox: PGtkHBox
|
hbox: PGtkHBox
|
||||||
e: PEditor
|
e: PEditor
|
||||||
PTab = ptr TTab
|
PTab = ptr TTab
|
||||||
|
|
||||||
TEditor = object of TObject
|
TEditor = object of TObject
|
||||||
window: PGtkWindow
|
window: PGtkWindow
|
||||||
statusbar: PGtkStatusBar
|
statusbar: PGtkStatusBar
|
||||||
|
|
@ -26,20 +26,20 @@ type
|
||||||
currTab: int
|
currTab: int
|
||||||
PEditor = ptr TEditor
|
PEditor = ptr TEditor
|
||||||
|
|
||||||
proc onWindowDestroy(obj: PGtkObject, event: PGdkEvent,
|
proc onWindowDestroy(obj: PGtkObject, event: PGdkEvent,
|
||||||
data: pointer): gboolean {.cdecl.} =
|
data: pointer): gboolean {.cdecl.} =
|
||||||
gtkMainQuit()
|
gtkMainQuit()
|
||||||
|
|
||||||
proc onAboutMenuItemActivate(menuItem: PGtkMenuItem, e: PEditor) {.cdecl.} =
|
proc onAboutMenuItemActivate(menuItem: PGtkMenuItem, e: PEditor) {.cdecl.} =
|
||||||
gtkShowAboutDialog(e.window,
|
gtkShowAboutDialog(e.window,
|
||||||
"comments", "A fast and leight-weight IDE for Nimrod",
|
"comments", "A fast and lightweight IDE for Nimrod",
|
||||||
"copyright", "Copyright \xc2\xa9 2009 Andreas Rumpf",
|
"copyright", "Copyright \xc2\xa9 2010 Andreas Rumpf",
|
||||||
"version", "0.1",
|
"version", "0.1",
|
||||||
"website", "http://nimrod.ethexor.com",
|
"website", "http://force7.de/nimrod/",
|
||||||
"program-name", "Nimrod IDE",
|
"program-name", "Nimrod IDE",
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
proc getTabIndex(e: PEditor, tab: PTab): int =
|
proc getTabIndex(e: PEditor, tab: PTab): int =
|
||||||
var i = 0
|
var i = 0
|
||||||
while true:
|
while true:
|
||||||
var w = gtkNotebookGetNthPage(e.notebook, i)
|
var w = gtkNotebookGetNthPage(e.notebook, i)
|
||||||
|
|
@ -47,43 +47,43 @@ proc getTabIndex(e: PEditor, tab: PTab): int =
|
||||||
var v = gtkNotebookGetTabLabel(e.notebook, w)
|
var v = gtkNotebookGetTabLabel(e.notebook, w)
|
||||||
if tab.hbox == v: return i
|
if tab.hbox == v: return i
|
||||||
inc(i)
|
inc(i)
|
||||||
|
|
||||||
proc getActiveTab(e: PEditor): PTab =
|
proc getActiveTab(e: PEditor): PTab =
|
||||||
nil
|
nil
|
||||||
|
|
||||||
type
|
type
|
||||||
TAnswer = enum
|
TAnswer = enum
|
||||||
answerYes, answerNo, answerCancel
|
answerYes, answerNo, answerCancel
|
||||||
|
|
||||||
proc askWhetherToSave(e: PEditor): TAnswer =
|
proc askWhetherToSave(e: PEditor): TAnswer =
|
||||||
var dialog = gtkDialogNewWithButtons("Should the changes be saved?",
|
var dialog = gtkDialogNewWithButtons("Should the changes be saved?",
|
||||||
e.window, GTK_DIALOG_MODAL, GTK_STOCK_SAVE, 1, "gtk-discard", 2,
|
e.window, GTK_DIALOG_MODAL, GTK_STOCK_SAVE, 1, "gtk-discard", 2,
|
||||||
GTK_STOCK_CANCEL, 3, nil)
|
GTK_STOCK_CANCEL, 3, nil)
|
||||||
result = TAnswer(gtkDialogRun(dialog)+1)
|
result = TAnswer(gtkDialogRun(dialog)+1)
|
||||||
gtkWidgetDestroy(dialog)
|
gtkWidgetDestroy(dialog)
|
||||||
|
|
||||||
proc saveTab(tab: PTab) =
|
proc saveTab(tab: PTab) =
|
||||||
if tab.untitled:
|
if tab.untitled:
|
||||||
tab.filename = ChooseFileToSave(tab.e.window, getRoot(tab))
|
tab.filename = ChooseFileToSave(tab.e.window, getRoot(tab))
|
||||||
tab.untitled = false
|
tab.untitled = false
|
||||||
XXX
|
XXX
|
||||||
|
|
||||||
proc OnCloseTab(button: PGtkButton, tab: PTab) {.cdecl.} =
|
proc OnCloseTab(button: PGtkButton, tab: PTab) {.cdecl.} =
|
||||||
var idx = -1
|
var idx = -1
|
||||||
for i in 0..high(tab.e.tabs):
|
for i in 0..high(tab.e.tabs):
|
||||||
if tab.e.tabs[i] == tab:
|
if tab.e.tabs[i] == tab:
|
||||||
idx = i
|
idx = i
|
||||||
break
|
break
|
||||||
if idx >= 0:
|
if idx >= 0:
|
||||||
if gtkTextBufferGetModified(gtkTextViewGetBuffer(tab.textView)):
|
if gtkTextBufferGetModified(gtkTextViewGetBuffer(tab.textView)):
|
||||||
case askWhetherToSave(tab.e)
|
case askWhetherToSave(tab.e)
|
||||||
of answerCancel: return
|
of answerCancel: return
|
||||||
of answerYes: saveTab(tab)
|
of answerYes: saveTab(tab)
|
||||||
of answerNo: nil
|
of answerNo: nil
|
||||||
|
|
||||||
gtkNotebookRemovePage(tab.e.notebook, idx)
|
gtkNotebookRemovePage(tab.e.notebook, idx)
|
||||||
if idx < high(tab.e.tabs):
|
if idx < high(tab.e.tabs):
|
||||||
for i in idx..high(tab.e.tabs)-1:
|
for i in idx..high(tab.e.tabs)-1:
|
||||||
tab.e.tabs[i] = tab.e.tabs[i+1]
|
tab.e.tabs[i] = tab.e.tabs[i+1]
|
||||||
else:
|
else:
|
||||||
dec currTab
|
dec currTab
|
||||||
|
|
@ -92,7 +92,7 @@ proc OnCloseTab(button: PGtkButton, tab: PTab) {.cdecl.} =
|
||||||
#var idx = getTabIndex(tab.e, tab)
|
#var idx = getTabIndex(tab.e, tab)
|
||||||
#if idx >= 0: gtk_notebook_remove_page(tab.e.notebook, idx)
|
#if idx >= 0: gtk_notebook_remove_page(tab.e.notebook, idx)
|
||||||
|
|
||||||
proc createTab(e: PEditor, filename: string, untitled: bool) =
|
proc createTab(e: PEditor, filename: string, untitled: bool) =
|
||||||
var t = cast[PTab](alloc0(sizeof(TTab)))
|
var t = cast[PTab](alloc0(sizeof(TTab)))
|
||||||
t.textview = gtkTextViewNewWithBuffer(gtkTextBufferNew(nil))
|
t.textview = gtkTextViewNewWithBuffer(gtkTextBufferNew(nil))
|
||||||
var fontDesc = pangoFontDescriptionFromString("monospace 10")
|
var fontDesc = pangoFontDescriptionFromString("monospace 10")
|
||||||
|
|
@ -104,7 +104,7 @@ proc createTab(e: PEditor, filename: string, untitled: bool) =
|
||||||
var scroll = gtkScrolledWindowNew(nil, nil)
|
var scroll = gtkScrolledWindowNew(nil, nil)
|
||||||
gtkContainerAdd(scroll, t.textview)
|
gtkContainerAdd(scroll, t.textview)
|
||||||
gtkWidgetShow(scroll)
|
gtkWidgetShow(scroll)
|
||||||
|
|
||||||
t.e = e
|
t.e = e
|
||||||
t.hbox = gtkHboxNew(false, 0)
|
t.hbox = gtkHboxNew(false, 0)
|
||||||
var image = gtkImageNewFromStock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU)
|
var image = gtkImageNewFromStock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU)
|
||||||
|
|
@ -114,16 +114,16 @@ proc createTab(e: PEditor, filename: string, untitled: bool) =
|
||||||
gtkButtonSetRelief(button, GTK_RELIEF_NONE)
|
gtkButtonSetRelief(button, GTK_RELIEF_NONE)
|
||||||
gtkBoxPackStart(t.hbox, lab, false, false, 2)
|
gtkBoxPackStart(t.hbox, lab, false, false, 2)
|
||||||
gtkBoxPackEnd(t.hbox, button, false, false, 0)
|
gtkBoxPackEnd(t.hbox, button, false, false, 0)
|
||||||
|
|
||||||
discard gSignalConnect(button, "clicked", G_Callback(onCloseTab), t)
|
discard gSignalConnect(button, "clicked", G_Callback(onCloseTab), t)
|
||||||
gtkWidgetShow(button)
|
gtkWidgetShow(button)
|
||||||
gtkWidgetShow(lab)
|
gtkWidgetShow(lab)
|
||||||
|
|
||||||
var idx = gtkNotebookAppendPage(e.notebook, scroll, t.hbox)
|
var idx = gtkNotebookAppendPage(e.notebook, scroll, t.hbox)
|
||||||
e.currTab = idx
|
e.currTab = idx
|
||||||
add(e.tabs, t)
|
add(e.tabs, t)
|
||||||
gtkNotebookSetCurrentPage(e.notebook, idx)
|
gtkNotebookSetCurrentPage(e.notebook, idx)
|
||||||
|
|
||||||
|
|
||||||
proc onOpenMenuItemActivate(menuItem: PGtkMenuItem, e: PEditor) {.cdecl.} =
|
proc onOpenMenuItemActivate(menuItem: PGtkMenuItem, e: PEditor) {.cdecl.} =
|
||||||
var files = ChooseFilesToOpen(e.window, getRoot(getActiveTab(e)))
|
var files = ChooseFilesToOpen(e.window, getRoot(getActiveTab(e)))
|
||||||
|
|
@ -131,8 +131,8 @@ proc onOpenMenuItemActivate(menuItem: PGtkMenuItem, e: PEditor) {.cdecl.} =
|
||||||
|
|
||||||
proc onSaveMenuItemActivate(menuItem: PGtkMenuItem, e: PEditor) {.cdecl.} =
|
proc onSaveMenuItemActivate(menuItem: PGtkMenuItem, e: PEditor) {.cdecl.} =
|
||||||
var cp = gtkNotebookGetCurrentPage(e.notebook)
|
var cp = gtkNotebookGetCurrentPage(e.notebook)
|
||||||
|
|
||||||
|
|
||||||
proc onSaveAsMenuItemActivate(menuItem: PGtkMenuItem, e: PEditor) {.cdecl.} =
|
proc onSaveAsMenuItemActivate(menuItem: PGtkMenuItem, e: PEditor) {.cdecl.} =
|
||||||
nil
|
nil
|
||||||
|
|
||||||
|
|
@ -140,7 +140,7 @@ proc onNewMenuItemActivate(menuItem: PGtkMenuItem, e: PEditor) {.cdecl.} =
|
||||||
inc(e.tabname)
|
inc(e.tabname)
|
||||||
createTab(e, "untitled-" & $e.tabname, true)
|
createTab(e, "untitled-" & $e.tabname, true)
|
||||||
|
|
||||||
proc main(e: PEditor) =
|
proc main(e: PEditor) =
|
||||||
var builder = gladeXmlNew(getApplicationDir() / GuiTemplate, nil, nil)
|
var builder = gladeXmlNew(getApplicationDir() / GuiTemplate, nil, nil)
|
||||||
if builder == nil: quit("cannot open: " & GuiTemplate)
|
if builder == nil: quit("cannot open: " & GuiTemplate)
|
||||||
# get the components:
|
# get the components:
|
||||||
|
|
@ -155,27 +155,27 @@ proc main(e: PEditor) =
|
||||||
gladeXmlSignalConnect(builder, "on_window_destroy",
|
gladeXmlSignalConnect(builder, "on_window_destroy",
|
||||||
GCallback(onWindowDestroy))
|
GCallback(onWindowDestroy))
|
||||||
var about = GTK_MENU_ITEM(gladeXmlGetWidget(builder, "about_menu_item"))
|
var about = GTK_MENU_ITEM(gladeXmlGetWidget(builder, "about_menu_item"))
|
||||||
discard gSignalConnect(about, "activate",
|
discard gSignalConnect(about, "activate",
|
||||||
G_CALLBACK(onAboutMenuItemActivate), e)
|
G_CALLBACK(onAboutMenuItemActivate), e)
|
||||||
|
|
||||||
var newItem = GTK_MENU_ITEM(gladeXmlGetWidget(builder, "new_menu_item"))
|
var newItem = GTK_MENU_ITEM(gladeXmlGetWidget(builder, "new_menu_item"))
|
||||||
discard gSignalConnect(newItem, "activate",
|
discard gSignalConnect(newItem, "activate",
|
||||||
G_CALLBACK(onNewMenuItemActivate), e)
|
G_CALLBACK(onNewMenuItemActivate), e)
|
||||||
|
|
||||||
var quitItem = GTK_MENU_ITEM(gladeXmlGetWidget(builder, "quit_menu_item"))
|
var quitItem = GTK_MENU_ITEM(gladeXmlGetWidget(builder, "quit_menu_item"))
|
||||||
discard gSignalConnect(quitItem, "activate",
|
discard gSignalConnect(quitItem, "activate",
|
||||||
G_CALLBACK(onWindowDestroy), e)
|
G_CALLBACK(onWindowDestroy), e)
|
||||||
|
|
||||||
var openItem = GTK_MENU_ITEM(gladeXmlGetWidget(builder, "open_menu_item"))
|
var openItem = GTK_MENU_ITEM(gladeXmlGetWidget(builder, "open_menu_item"))
|
||||||
discard gSignalConnect(openItem, "activate",
|
discard gSignalConnect(openItem, "activate",
|
||||||
G_CALLBACK(onOpenMenuItemActivate), e)
|
G_CALLBACK(onOpenMenuItemActivate), e)
|
||||||
|
|
||||||
var saveItem = GTK_MENU_ITEM(gladeXmlGetWidget(builder, "save_menu_item"))
|
var saveItem = GTK_MENU_ITEM(gladeXmlGetWidget(builder, "save_menu_item"))
|
||||||
discard gSignalConnect(saveItem, "activate",
|
discard gSignalConnect(saveItem, "activate",
|
||||||
G_CALLBACK(onSaveMenuItemActivate), e)
|
G_CALLBACK(onSaveMenuItemActivate), e)
|
||||||
|
|
||||||
var saveAsItem = GTK_MENU_ITEM(gladeXmlGetWidget(builder, "save_as_menu_item"))
|
var saveAsItem = GTK_MENU_ITEM(gladeXmlGetWidget(builder, "save_as_menu_item"))
|
||||||
discard gSignalConnect(saveAsItem, "activate",
|
discard gSignalConnect(saveAsItem, "activate",
|
||||||
G_CALLBACK(onSaveAsMenuItemActivate), e)
|
G_CALLBACK(onSaveAsMenuItemActivate), e)
|
||||||
|
|
||||||
gtkWindowSetDefaultIconName(GTK_STOCK_EDIT)
|
gtkWindowSetDefaultIconName(GTK_STOCK_EDIT)
|
||||||
|
|
|
||||||
|
|
@ -7,19 +7,19 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
## This module implements a simple HTTP-Server.
|
## This module implements a simple HTTP-Server.
|
||||||
##
|
##
|
||||||
## Example:
|
## Example:
|
||||||
##
|
##
|
||||||
## .. code-block:: nimrod
|
## .. code-block:: nimrod
|
||||||
## import strutils, sockets, httpserver
|
## import strutils, sockets, httpserver
|
||||||
##
|
##
|
||||||
## var counter = 0
|
## var counter = 0
|
||||||
## proc handleRequest(client: TSocket, path, query: string): bool {.procvar.} =
|
## proc handleRequest(client: TSocket, path, query: string): bool {.procvar.} =
|
||||||
## inc(counter)
|
## inc(counter)
|
||||||
## client.send("Hallo for the $#th time." % $counter & wwwNL)
|
## client.send("Hello for the $#th time." % $counter & wwwNL)
|
||||||
## return false # do not stop processing
|
## return false # do not stop processing
|
||||||
##
|
##
|
||||||
## run(handleRequest, TPort(80))
|
## run(handleRequest, TPort(80))
|
||||||
##
|
##
|
||||||
|
|
||||||
|
|
@ -47,7 +47,7 @@ proc cannotExec(client: TSocket) =
|
||||||
sendTextContentType(client)
|
sendTextContentType(client)
|
||||||
send(client, "<P>Error prohibited CGI execution." & wwwNL)
|
send(client, "<P>Error prohibited CGI execution." & wwwNL)
|
||||||
|
|
||||||
proc headers(client: TSocket, filename: string) =
|
proc headers(client: TSocket, filename: string) =
|
||||||
# XXX could use filename to determine file type
|
# XXX could use filename to determine file type
|
||||||
send(client, "HTTP/1.0 200 OK" & wwwNL)
|
send(client, "HTTP/1.0 200 OK" & wwwNL)
|
||||||
send(client, ServerSig)
|
send(client, ServerSig)
|
||||||
|
|
@ -60,16 +60,16 @@ proc notFound(client: TSocket) =
|
||||||
send(client, "<html><title>Not Found</title>" & wwwNL)
|
send(client, "<html><title>Not Found</title>" & wwwNL)
|
||||||
send(client, "<body><p>The server could not fulfill" & wwwNL)
|
send(client, "<body><p>The server could not fulfill" & wwwNL)
|
||||||
send(client, "your request because the resource specified" & wwwNL)
|
send(client, "your request because the resource specified" & wwwNL)
|
||||||
send(client, "is unavailable or nonexistent." & wwwNL)
|
send(client, "is unavailable or nonexistent.</p>" & wwwNL)
|
||||||
send(client, "</body></html>" & wwwNL)
|
send(client, "</body></html>" & wwwNL)
|
||||||
|
|
||||||
proc unimplemented(client: TSocket) =
|
proc unimplemented(client: TSocket) =
|
||||||
send(client, "HTTP/1.0 501 Method Not Implemented" & wwwNL)
|
send(client, "HTTP/1.0 501 Method Not Implemented" & wwwNL)
|
||||||
send(client, ServerSig)
|
send(client, ServerSig)
|
||||||
sendTextContentType(client)
|
sendTextContentType(client)
|
||||||
send(client, "<html><head><title>Method Not Implemented" &
|
send(client, "<html><head><title>Method Not Implemented" &
|
||||||
"</title></head>" &
|
"</title></head>" &
|
||||||
"<body><p>HTTP request method not supported." &
|
"<body><p>HTTP request method not supported.</p>" &
|
||||||
"</body></HTML>" & wwwNL)
|
"</body></HTML>" & wwwNL)
|
||||||
|
|
||||||
# ----------------- file serving ---------------------------------------------
|
# ----------------- file serving ---------------------------------------------
|
||||||
|
|
@ -78,7 +78,7 @@ proc discardHeaders(client: TSocket) = skip(client)
|
||||||
|
|
||||||
proc serveFile(client: TSocket, filename: string) =
|
proc serveFile(client: TSocket, filename: string) =
|
||||||
discardHeaders(client)
|
discardHeaders(client)
|
||||||
|
|
||||||
var f: TFile
|
var f: TFile
|
||||||
if open(f, filename):
|
if open(f, filename):
|
||||||
headers(client, filename)
|
headers(client, filename)
|
||||||
|
|
@ -109,7 +109,7 @@ proc executeCgi(client: TSocket, path, query: string, meth: TRequestMethod) =
|
||||||
case meth
|
case meth
|
||||||
of reqGet:
|
of reqGet:
|
||||||
discardHeaders(client)
|
discardHeaders(client)
|
||||||
|
|
||||||
env["REQUEST_METHOD"] = "GET"
|
env["REQUEST_METHOD"] = "GET"
|
||||||
env["QUERY_STRING"] = query
|
env["QUERY_STRING"] = query
|
||||||
of reqPost:
|
of reqPost:
|
||||||
|
|
@ -122,16 +122,16 @@ proc executeCgi(client: TSocket, path, query: string, meth: TRequestMethod) =
|
||||||
var i = len("content-length:")
|
var i = len("content-length:")
|
||||||
while L[i] in Whitespace: inc(i)
|
while L[i] in Whitespace: inc(i)
|
||||||
contentLength = parseInt(copy(L, i))
|
contentLength = parseInt(copy(L, i))
|
||||||
|
|
||||||
if contentLength < 0:
|
if contentLength < 0:
|
||||||
badRequest(client)
|
badRequest(client)
|
||||||
return
|
return
|
||||||
|
|
||||||
env["REQUEST_METHOD"] = "POST"
|
env["REQUEST_METHOD"] = "POST"
|
||||||
env["CONTENT_LENGTH"] = $contentLength
|
env["CONTENT_LENGTH"] = $contentLength
|
||||||
|
|
||||||
send(client, "HTTP/1.0 200 OK" & wwwNL)
|
send(client, "HTTP/1.0 200 OK" & wwwNL)
|
||||||
|
|
||||||
var process = startProcess(command=path, env=env)
|
var process = startProcess(command=path, env=env)
|
||||||
if meth == reqPost:
|
if meth == reqPost:
|
||||||
# get from client and post to CGI program:
|
# get from client and post to CGI program:
|
||||||
|
|
@ -139,7 +139,7 @@ proc executeCgi(client: TSocket, path, query: string, meth: TRequestMethod) =
|
||||||
if recv(client, buf, contentLength) != contentLength: OSError()
|
if recv(client, buf, contentLength) != contentLength: OSError()
|
||||||
var inp = process.inputStream
|
var inp = process.inputStream
|
||||||
inp.writeData(inp, buf, contentLength)
|
inp.writeData(inp, buf, contentLength)
|
||||||
|
|
||||||
var outp = process.outputStream
|
var outp = process.outputStream
|
||||||
while running(process) or not outp.atEnd(outp):
|
while running(process) or not outp.atEnd(outp):
|
||||||
var line = outp.readLine()
|
var line = outp.readLine()
|
||||||
|
|
@ -165,11 +165,11 @@ proc acceptRequest(client: TSocket) =
|
||||||
meth = reqPost
|
meth = reqPost
|
||||||
else:
|
else:
|
||||||
unimplemented(client)
|
unimplemented(client)
|
||||||
|
|
||||||
var path = data[1]
|
var path = data[1]
|
||||||
if path[path.len-1] == '/' or existsDir(path):
|
if path[path.len-1] == '/' or existsDir(path):
|
||||||
path = path / "index.html"
|
path = path / "index.html"
|
||||||
|
|
||||||
if not ExistsFile(path):
|
if not ExistsFile(path):
|
||||||
discardHeaders(client)
|
discardHeaders(client)
|
||||||
notFound(client)
|
notFound(client)
|
||||||
|
|
@ -193,15 +193,15 @@ type
|
||||||
port: TPort
|
port: TPort
|
||||||
client*: TSocket ## the socket to write the file data to
|
client*: TSocket ## the socket to write the file data to
|
||||||
path*, query*: string ## path and query the client requested
|
path*, query*: string ## path and query the client requested
|
||||||
|
|
||||||
proc open*(s: var TServer, port = TPort(80)) =
|
proc open*(s: var TServer, port = TPort(80)) =
|
||||||
## creates a new server at port `port`. If ``port == 0`` a free port is
|
## creates a new server at port `port`. If ``port == 0`` a free port is
|
||||||
## aquired that can be accessed later by the ``port`` proc.
|
## acquired that can be accessed later by the ``port`` proc.
|
||||||
s.socket = socket(AF_INET)
|
s.socket = socket(AF_INET)
|
||||||
if s.socket == InvalidSocket: OSError()
|
if s.socket == InvalidSocket: OSError()
|
||||||
bindAddr(s.socket, port)
|
bindAddr(s.socket, port)
|
||||||
listen(s.socket)
|
listen(s.socket)
|
||||||
|
|
||||||
if port == TPort(0):
|
if port == TPort(0):
|
||||||
s.port = getSockName(s.socket)
|
s.port = getSockName(s.socket)
|
||||||
else:
|
else:
|
||||||
|
|
@ -209,12 +209,12 @@ proc open*(s: var TServer, port = TPort(80)) =
|
||||||
s.client = InvalidSocket
|
s.client = InvalidSocket
|
||||||
s.path = ""
|
s.path = ""
|
||||||
s.query = ""
|
s.query = ""
|
||||||
|
|
||||||
proc port*(s: var TServer): TPort =
|
proc port*(s: var TServer): TPort =
|
||||||
## get the port number the server has aquired.
|
## get the port number the server has acquired.
|
||||||
result = s.port
|
result = s.port
|
||||||
|
|
||||||
proc next*(s: var TServer) =
|
proc next*(s: var TServer) =
|
||||||
## proceed to the first/next request.
|
## proceed to the first/next request.
|
||||||
s.client = accept(s.socket)
|
s.client = accept(s.socket)
|
||||||
headers(s.client, "")
|
headers(s.client, "")
|
||||||
|
|
@ -236,13 +236,13 @@ proc close*(s: TServer) =
|
||||||
## closes the server (and the socket the server uses).
|
## closes the server (and the socket the server uses).
|
||||||
close(s.socket)
|
close(s.socket)
|
||||||
|
|
||||||
proc run*(handleRequest: proc (client: TSocket, path, query: string): bool,
|
proc run*(handleRequest: proc (client: TSocket, path, query: string): bool,
|
||||||
port = TPort(80)) =
|
port = TPort(80)) =
|
||||||
## encapsulates the server object and main loop
|
## encapsulates the server object and main loop
|
||||||
var s: TServer
|
var s: TServer
|
||||||
open(s, port)
|
open(s, port)
|
||||||
#echo("httpserver running on port ", s.port)
|
#echo("httpserver running on port ", s.port)
|
||||||
while true:
|
while true:
|
||||||
next(s)
|
next(s)
|
||||||
if handleRequest(s.client, s.path, s.query): break
|
if handleRequest(s.client, s.path, s.query): break
|
||||||
close(s.client)
|
close(s.client)
|
||||||
|
|
@ -252,8 +252,8 @@ when isMainModule:
|
||||||
var counter = 0
|
var counter = 0
|
||||||
proc handleRequest(client: TSocket, path, query: string): bool {.procvar.} =
|
proc handleRequest(client: TSocket, path, query: string): bool {.procvar.} =
|
||||||
inc(counter)
|
inc(counter)
|
||||||
client.send("Hallo, Andreas for the $#th time." % $counter & wwwNL)
|
client.send("Hello, Andreas, for the $#th time." % $counter & wwwNL)
|
||||||
return false # do not stop processing
|
return false # do not stop processing
|
||||||
|
|
||||||
run(handleRequest, TPort(80))
|
run(handleRequest, TPort(80))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ proc execCmd*(command: string): int
|
||||||
proc executeCommand*(command: string): int {.deprecated.} =
|
proc executeCommand*(command: string): int {.deprecated.} =
|
||||||
## **Deprecated since version 0.8.2**: Use `execCmd` instead.
|
## **Deprecated since version 0.8.2**: Use `execCmd` instead.
|
||||||
result = execCmd(command)
|
result = execCmd(command)
|
||||||
|
|
||||||
|
|
||||||
proc startProcess*(command: string,
|
proc startProcess*(command: string,
|
||||||
workingDir: string = "",
|
workingDir: string = "",
|
||||||
|
|
@ -115,7 +115,7 @@ when defined(macosx) or defined(bsd):
|
||||||
a: var int, b: pointer, c: int): cint {.
|
a: var int, b: pointer, c: int): cint {.
|
||||||
importc: "sysctl", header: "<sys/sysctl.h>".}
|
importc: "sysctl", header: "<sys/sysctl.h>".}
|
||||||
|
|
||||||
proc countProcessors*(): int =
|
proc countProcessors*(): int =
|
||||||
## returns the numer of the processors/cores the machine has.
|
## returns the numer of the processors/cores the machine has.
|
||||||
## Returns 0 if it cannot be determined.
|
## Returns 0 if it cannot be determined.
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
|
|
@ -186,7 +186,7 @@ proc execProcesses*(cmds: openArray[string],
|
||||||
inc(i)
|
inc(i)
|
||||||
if i > high(cmds): break
|
if i > high(cmds): break
|
||||||
for i in 0..m-1:
|
for i in 0..m-1:
|
||||||
result = max(waitForExit(q[i]), result)
|
result = max(waitForExit(q[i]), result)
|
||||||
else:
|
else:
|
||||||
for i in 0..high(cmds):
|
for i in 0..high(cmds):
|
||||||
var p = startProcessAux(cmds[i], options=options)
|
var p = startProcessAux(cmds[i], options=options)
|
||||||
|
|
@ -243,7 +243,7 @@ when defined(Windows):
|
||||||
if a == 0 and br != 0: OSError()
|
if a == 0 and br != 0: OSError()
|
||||||
s.atTheEnd = br < bufLen
|
s.atTheEnd = br < bufLen
|
||||||
result = br
|
result = br
|
||||||
|
|
||||||
proc hsWriteData(s: PFileHandleStream, buffer: pointer, bufLen: int) =
|
proc hsWriteData(s: PFileHandleStream, buffer: pointer, bufLen: int) =
|
||||||
var bytesWritten: int32
|
var bytesWritten: int32
|
||||||
var a = winlean.writeFile(s.handle, buffer, bufLen, bytesWritten, nil)
|
var a = winlean.writeFile(s.handle, buffer, bufLen, bytesWritten, nil)
|
||||||
|
|
@ -256,10 +256,10 @@ when defined(Windows):
|
||||||
result.atEnd = hsAtEnd
|
result.atEnd = hsAtEnd
|
||||||
result.readData = hsReadData
|
result.readData = hsReadData
|
||||||
result.writeData = hsWriteData
|
result.writeData = hsWriteData
|
||||||
|
|
||||||
proc buildCommandLine(a: string, args: openarray[string]): cstring =
|
proc buildCommandLine(a: string, args: openarray[string]): cstring =
|
||||||
var res = quoteIfContainsWhite(a)
|
var res = quoteIfContainsWhite(a)
|
||||||
for i in 0..high(args):
|
for i in 0..high(args):
|
||||||
res.add(' ')
|
res.add(' ')
|
||||||
res.add(quoteIfContainsWhite(args[i]))
|
res.add(quoteIfContainsWhite(args[i]))
|
||||||
result = cast[cstring](alloc0(res.len+1))
|
result = cast[cstring](alloc0(res.len+1))
|
||||||
|
|
@ -324,7 +324,7 @@ when defined(Windows):
|
||||||
result.inputHandle = si.hStdInput
|
result.inputHandle = si.hStdInput
|
||||||
result.outputHandle = si.hStdOutput
|
result.outputHandle = si.hStdOutput
|
||||||
result.errorHandle = si.hStdError
|
result.errorHandle = si.hStdError
|
||||||
|
|
||||||
var cmdl: cstring
|
var cmdl: cstring
|
||||||
if false: # poUseShell in options:
|
if false: # poUseShell in options:
|
||||||
cmdl = buildCommandLine(getEnv("COMSPEC"), @["/c", command] & args)
|
cmdl = buildCommandLine(getEnv("COMSPEC"), @["/c", command] & args)
|
||||||
|
|
@ -337,13 +337,13 @@ when defined(Windows):
|
||||||
if poEchoCmd in options: echo($cmdl)
|
if poEchoCmd in options: echo($cmdl)
|
||||||
success = winlean.CreateProcess(nil,
|
success = winlean.CreateProcess(nil,
|
||||||
cmdl, nil, nil, 1, NORMAL_PRIORITY_CLASS, e, wd, SI, ProcInfo)
|
cmdl, nil, nil, 1, NORMAL_PRIORITY_CLASS, e, wd, SI, ProcInfo)
|
||||||
|
|
||||||
if poParentStreams notin options:
|
if poParentStreams notin options:
|
||||||
FileClose(si.hStdInput)
|
FileClose(si.hStdInput)
|
||||||
FileClose(si.hStdOutput)
|
FileClose(si.hStdOutput)
|
||||||
if poStdErrToStdOut notin options:
|
if poStdErrToStdOut notin options:
|
||||||
FileClose(si.hStdError)
|
FileClose(si.hStdError)
|
||||||
|
|
||||||
if e != nil: dealloc(e)
|
if e != nil: dealloc(e)
|
||||||
dealloc(cmdl)
|
dealloc(cmdl)
|
||||||
if success == 0: OSError()
|
if success == 0: OSError()
|
||||||
|
|
@ -382,7 +382,7 @@ when defined(Windows):
|
||||||
proc errorStream(p: PProcess): PStream =
|
proc errorStream(p: PProcess): PStream =
|
||||||
result = newFileHandleStream(p.errorHandle)
|
result = newFileHandleStream(p.errorHandle)
|
||||||
|
|
||||||
proc execCmd(command: string): int =
|
proc execCmd(command: string): int =
|
||||||
var
|
var
|
||||||
SI: TStartupInfo
|
SI: TStartupInfo
|
||||||
ProcInfo: TProcessInformation
|
ProcInfo: TProcessInformation
|
||||||
|
|
@ -535,7 +535,7 @@ else:
|
||||||
|
|
||||||
proc csystem(cmd: cstring): cint {.nodecl, importc: "system".}
|
proc csystem(cmd: cstring): cint {.nodecl, importc: "system".}
|
||||||
|
|
||||||
proc execCmd(command: string): int =
|
proc execCmd(command: string): int =
|
||||||
result = csystem(command)
|
result = csystem(command)
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -9,12 +9,12 @@
|
||||||
|
|
||||||
## This module implements Nimrod's support for the ``variant`` datatype.
|
## This module implements Nimrod's support for the ``variant`` datatype.
|
||||||
## `TVariant` shows how the flexibility of dynamic typing is achieved
|
## `TVariant` shows how the flexibility of dynamic typing is achieved
|
||||||
## within a static type system.
|
## within a static type system.
|
||||||
|
|
||||||
type
|
type
|
||||||
TVarType* = enum
|
TVarType* = enum
|
||||||
vtNone,
|
vtNone,
|
||||||
vtBool,
|
vtBool,
|
||||||
vtChar,
|
vtChar,
|
||||||
vtEnum,
|
vtEnum,
|
||||||
vtInt,
|
vtInt,
|
||||||
|
|
@ -31,7 +31,7 @@ type
|
||||||
of vtString: vstring: string
|
of vtString: vstring: string
|
||||||
of vtSet, vtSeq: q: seq[TVariant]
|
of vtSet, vtSeq: q: seq[TVariant]
|
||||||
of vtDict: d: seq[tuple[key, val: TVariant]]
|
of vtDict: d: seq[tuple[key, val: TVariant]]
|
||||||
|
|
||||||
iterator objectFields*[T](x: T, skipInherited: bool): tuple[
|
iterator objectFields*[T](x: T, skipInherited: bool): tuple[
|
||||||
key: string, val: TVariant] {.magic: "ObjectFields"}
|
key: string, val: TVariant] {.magic: "ObjectFields"}
|
||||||
|
|
||||||
|
|
@ -74,10 +74,10 @@ proc `?`* [T: object](x: T): TVariant {.magic: "ToVariant".}
|
||||||
|
|
||||||
proc `><`*[T](v: TVariant, typ: T): T {.magic: "FromVariant".}
|
proc `><`*[T](v: TVariant, typ: T): T {.magic: "FromVariant".}
|
||||||
|
|
||||||
?[?5, ?67, ?"hallo"]
|
?[?5, ?67, ?"hello"]
|
||||||
myVar?int
|
myVar?int
|
||||||
|
|
||||||
|
|
||||||
proc `==`* (x, y: TVariant): bool =
|
proc `==`* (x, y: TVariant): bool =
|
||||||
if x.vtype == y.vtype:
|
if x.vtype == y.vtype:
|
||||||
case x.vtype
|
case x.vtype
|
||||||
|
|
@ -139,7 +139,7 @@ proc `[]=`* (a, b, c: TVariant) =
|
||||||
a.d[b.vint].val = c
|
a.d[b.vint].val = c
|
||||||
variantError()
|
variantError()
|
||||||
else: variantError()
|
else: variantError()
|
||||||
|
|
||||||
proc `[]`* (a: TVariant, b: int): TVariant {.inline} = return a[?b]
|
proc `[]`* (a: TVariant, b: int): TVariant {.inline} = return a[?b]
|
||||||
proc `[]`* (a: TVariant, b: string): TVariant {.inline} = return a[?b]
|
proc `[]`* (a: TVariant, b: string): TVariant {.inline} = return a[?b]
|
||||||
proc `[]=`* (a: TVariant, b: int, c: TVariant) {.inline} = a[?b] = c
|
proc `[]=`* (a: TVariant, b: int, c: TVariant) {.inline} = a[?b] = c
|
||||||
|
|
@ -154,9 +154,9 @@ proc `+`* (x, y: TVariant): TVariant =
|
||||||
else:
|
else:
|
||||||
case y.vtype
|
case y.vtype
|
||||||
of vtBool, vtChar, vtEnum, vtInt:
|
of vtBool, vtChar, vtEnum, vtInt:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
vint: int64
|
vint: int64
|
||||||
of vtFloat: vfloat: float64
|
of vtFloat: vfloat: float64
|
||||||
of vtString: vstring: string
|
of vtString: vstring: string
|
||||||
|
|
@ -171,11 +171,11 @@ proc `mod`* (x, y: TVariant): TVariant
|
||||||
proc `&`* (x, y: TVariant): TVariant
|
proc `&`* (x, y: TVariant): TVariant
|
||||||
proc `$`* (x: TVariant): string =
|
proc `$`* (x: TVariant): string =
|
||||||
# uses JS notation
|
# uses JS notation
|
||||||
|
|
||||||
proc parseVariant*(s: string): TVariant
|
proc parseVariant*(s: string): TVariant
|
||||||
proc `<`* (x, y: TVariant): bool
|
proc `<`* (x, y: TVariant): bool
|
||||||
proc `<=`* (x, y: TVariant): bool
|
proc `<=`* (x, y: TVariant): bool
|
||||||
|
|
||||||
proc hash*(x: TVariant): int =
|
proc hash*(x: TVariant): int =
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
3209
lib/system.nim
3209
lib/system.nim
File diff suppressed because it is too large
Load diff
|
|
@ -104,7 +104,7 @@ proc addChar(s: NimString, c: char): NimString {.compilerProc.} =
|
||||||
|
|
||||||
# These routines should be used like following:
|
# These routines should be used like following:
|
||||||
# <Nimrod code>
|
# <Nimrod code>
|
||||||
# s &= "hallo " & name & " how do you feel?"
|
# s &= "Hello " & name & ", how do you feel?"
|
||||||
#
|
#
|
||||||
# <generated C code>
|
# <generated C code>
|
||||||
# {
|
# {
|
||||||
|
|
@ -115,7 +115,7 @@ proc addChar(s: NimString, c: char): NimString {.compilerProc.} =
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
# <Nimrod code>
|
# <Nimrod code>
|
||||||
# s = "hallo " & name & " how do you feel?"
|
# s = "Hello " & name & ", how do you feel?"
|
||||||
#
|
#
|
||||||
# <generated C code>
|
# <generated C code>
|
||||||
# {
|
# {
|
||||||
|
|
@ -180,8 +180,8 @@ proc incrSeq(seq: PGenericSeq, elemSize: int): PGenericSeq {.compilerProc.} =
|
||||||
result = cast[PGenericSeq](newSeq(extGetCellType(seq), s))
|
result = cast[PGenericSeq](newSeq(extGetCellType(seq), s))
|
||||||
genericSeqAssign(result, seq, XXX)
|
genericSeqAssign(result, seq, XXX)
|
||||||
#copyMem(result, seq, seq.len * elemSize + GenericSeqSize)
|
#copyMem(result, seq, seq.len * elemSize + GenericSeqSize)
|
||||||
inc(result.len)
|
inc(result.len)
|
||||||
else:
|
else:
|
||||||
result = seq
|
result = seq
|
||||||
if result.len >= result.space:
|
if result.len >= result.space:
|
||||||
result.space = resize(result.space)
|
result.space = resize(result.space)
|
||||||
|
|
@ -214,7 +214,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
|
||||||
# we need to decref here, otherwise the GC leaks!
|
# we need to decref here, otherwise the GC leaks!
|
||||||
when not defined(boehmGC) and not defined(nogc):
|
when not defined(boehmGC) and not defined(nogc):
|
||||||
for i in newLen..result.len-1:
|
for i in newLen..result.len-1:
|
||||||
forAllChildrenAux(cast[pointer](cast[TAddress](result) +%
|
forAllChildrenAux(cast[pointer](cast[TAddress](result) +%
|
||||||
GenericSeqSize +% (i*%elemSize)),
|
GenericSeqSize +% (i*%elemSize)),
|
||||||
extGetCellType(result).base, waZctDecRef)
|
extGetCellType(result).base, waZctDecRef)
|
||||||
# and set the memory to nil:
|
# and set the memory to nil:
|
||||||
|
|
|
||||||
197
lib/windows/psapi.nim
Normal file
197
lib/windows/psapi.nim
Normal file
|
|
@ -0,0 +1,197 @@
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Nimrod's Runtime Library
|
||||||
|
# (c) Copyright 2009 Andreas Rumpf
|
||||||
|
#
|
||||||
|
# See the file "copying.txt", included in this
|
||||||
|
# distribution, for details about the copyright.
|
||||||
|
#
|
||||||
|
# PSAPI interface unit
|
||||||
|
|
||||||
|
# Contains the definitions for the APIs provided by PSAPI.DLL
|
||||||
|
|
||||||
|
import # Data structure templates
|
||||||
|
Windows
|
||||||
|
|
||||||
|
proc EnumProcesses*(lpidProcess: ptr DWORD, cb: DWORD, cbNeeded: ptr DWORD): WINBOOL {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "EnumProcesses".}
|
||||||
|
proc EnumProcessModules*(hProcess: HANDLE, lphModule: ptr HMODULE, cb: DWORD, lpcbNeeded: LPDWORD): WINBOOL {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "EnumProcessModules".}
|
||||||
|
|
||||||
|
proc GetModuleBaseNameA*(hProcess: HANDLE, hModule: HMODULE, lpBaseName: LPSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetModuleBaseNameA".}
|
||||||
|
proc GetModuleBaseNameW*(hProcess: HANDLE, hModule: HMODULE, lpBaseName: LPWSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetModuleBaseNameW".}
|
||||||
|
when defined(winUnicode):
|
||||||
|
proc GetModuleBaseName*(hProcess: HANDLE, hModule: HMODULE, lpBaseName: LPWSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetModuleBaseNameW".}
|
||||||
|
else:
|
||||||
|
proc GetModuleBaseName*(hProcess: HANDLE, hModule: HMODULE, lpBaseName: LPSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetModuleBaseNameA".}
|
||||||
|
|
||||||
|
proc GetModuleFileNameExA*(hProcess: HANDLE, hModule: HMODULE, lpFileNameEx: LPSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetModuleFileNameExA".}
|
||||||
|
proc GetModuleFileNameExW*(hProcess: HANDLE, hModule: HMODULE, lpFileNameEx: LPWSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetModuleFileNameExW".}
|
||||||
|
when defined(winUnicode):
|
||||||
|
proc GetModuleFileNameEx*(hProcess: HANDLE, hModule: HMODULE, lpFileNameEx: LPWSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetModuleFileNameExW".}
|
||||||
|
else:
|
||||||
|
proc GetModuleFileNameEx*(hProcess: HANDLE, hModule: HMODULE, lpFileNameEx: LPSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetModuleFileNameExA".}
|
||||||
|
|
||||||
|
type
|
||||||
|
MODULEINFO* {.final.} = object
|
||||||
|
lpBaseOfDll*: LPVOID
|
||||||
|
SizeOfImage*: DWORD
|
||||||
|
EntryPoint*: LPVOID
|
||||||
|
LPMODULEINFO* = ptr MODULEINFO
|
||||||
|
|
||||||
|
proc GetModuleInformation*(hProcess: HANDLE, hModule: HMODULE, lpmodinfo: LPMODULEINFO, cb: DWORD): WINBOOL {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetModuleInformation".}
|
||||||
|
proc EmptyWorkingSet*(hProcess: HANDLE): WINBOOL {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "EmptyWorkingSet".}
|
||||||
|
proc QueryWorkingSet*(hProcess: HANDLE, pv: PVOID, cb: DWORD): WINBOOL {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "QueryWorkingSet".}
|
||||||
|
proc QueryWorkingSetEx*(hProcess: HANDLE, pv: PVOID, cb: DWORD): WINBOOL {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "QueryWorkingSetEx".}
|
||||||
|
proc InitializeProcessForWsWatch*(hProcess: HANDLE): WINBOOL {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "InitializeProcessForWsWatch".}
|
||||||
|
|
||||||
|
type
|
||||||
|
PSAPI_WS_WATCH_INFORMATION* {.final.} = object
|
||||||
|
FaultingPc*: LPVOID
|
||||||
|
FaultingVa*: LPVOID
|
||||||
|
PPSAPI_WS_WATCH_INFORMATION* = ptr PSAPI_WS_WATCH_INFORMATION
|
||||||
|
|
||||||
|
proc GetWsChanges*(hProcess: HANDLE, lpWatchInfo: PPSAPI_WS_WATCH_INFORMATION, cb: DWORD): WINBOOL {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetWsChanges".}
|
||||||
|
|
||||||
|
proc GetMappedFileNameA*(hProcess: HANDLE, lpv: LPVOID, lpFilename: LPSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetMappedFileNameA".}
|
||||||
|
proc GetMappedFileNameW*(hProcess: HANDLE, lpv: LPVOID, lpFilename: LPWSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetMappedFileNameW".}
|
||||||
|
when defined(winUnicode):
|
||||||
|
proc GetMappedFileName*(hProcess: HANDLE, lpv: LPVOID, lpFilename: LPWSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetMappedFileNameW".}
|
||||||
|
else:
|
||||||
|
proc GetMappedFileName*(hProcess: HANDLE, lpv: LPVOID, lpFilename: LPSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetMappedFileNameA".}
|
||||||
|
|
||||||
|
proc EnumDeviceDrivers*(lpImageBase: LPVOID, cb: DWORD, lpcbNeeded: LPDWORD): WINBOOL {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "EnumDeviceDrivers".}
|
||||||
|
|
||||||
|
proc GetDeviceDriverBaseNameA*(ImageBase: LPVOID, lpBaseName: LPSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetDeviceDriverBaseNameA".}
|
||||||
|
proc GetDeviceDriverBaseNameW*(ImageBase: LPVOID, lpBaseName: LPWSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetDeviceDriverBaseNameW".}
|
||||||
|
when defined(winUnicode):
|
||||||
|
proc GetDeviceDriverBaseName*(ImageBase: LPVOID, lpBaseName: LPWSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetDeviceDriverBaseNameW".}
|
||||||
|
else:
|
||||||
|
proc GetDeviceDriverBaseName*(ImageBase: LPVOID, lpBaseName: LPSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetDeviceDriverBaseNameA".}
|
||||||
|
|
||||||
|
proc GetDeviceDriverFileNameA*(ImageBase: LPVOID, lpFileName: LPSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetDeviceDriverFileNameA".}
|
||||||
|
proc GetDeviceDriverFileNameW*(ImageBase: LPVOID, lpFileName: LPWSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetDeviceDriverFileNameW".}
|
||||||
|
when defined(winUnicode):
|
||||||
|
proc GetDeviceDriverFileName*(ImageBase: LPVOID, lpFileName: LPWSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetDeviceDriverFileNameW".}
|
||||||
|
else:
|
||||||
|
proc GetDeviceDriverFileName*(ImageBase: LPVOID, lpFileName: LPSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetDeviceDriverFileNameA".}
|
||||||
|
|
||||||
|
type
|
||||||
|
PROCESS_MEMORY_COUNTERS* {.final.} = object
|
||||||
|
cb*: DWORD
|
||||||
|
PageFaultCount*: DWORD
|
||||||
|
PeakWorkingSetSize: SIZE_T
|
||||||
|
WorkingSetSize: SIZE_T
|
||||||
|
QuotaPeakPagedPoolUsage: SIZE_T
|
||||||
|
QuotaPagedPoolUsage: SIZE_T
|
||||||
|
QuotaPeakNonPagedPoolUsage: SIZE_T
|
||||||
|
QuotaNonPagedPoolUsage: SIZE_T
|
||||||
|
PagefileUsage: SIZE_T
|
||||||
|
PeakPagefileUsage: SIZE_T
|
||||||
|
PPROCESS_MEMORY_COUNTERS* = ptr PROCESS_MEMORY_COUNTERS
|
||||||
|
|
||||||
|
type
|
||||||
|
PROCESS_MEMORY_COUNTERS_EX* {.final.} = object
|
||||||
|
cb*: DWORD
|
||||||
|
PageFaultCount*: DWORD
|
||||||
|
PeakWorkingSetSize: SIZE_T
|
||||||
|
WorkingSetSize: SIZE_T
|
||||||
|
QuotaPeakPagedPoolUsage: SIZE_T
|
||||||
|
QuotaPagedPoolUsage: SIZE_T
|
||||||
|
QuotaPeakNonPagedPoolUsage: SIZE_T
|
||||||
|
QuotaNonPagedPoolUsage: SIZE_T
|
||||||
|
PagefileUsage: SIZE_T
|
||||||
|
PeakPagefileUsage: SIZE_T
|
||||||
|
PrivateUsage: SIZE_T
|
||||||
|
PPROCESS_MEMORY_COUNTERS_EX* = ptr PROCESS_MEMORY_COUNTERS_EX
|
||||||
|
|
||||||
|
proc GetProcessMemoryInfo*(hProcess: HANDLE, ppsmemCounters: PPROCESS_MEMORY_COUNTERS, cb: DWORD): WINBOOL {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetProcessMemoryInfo".}
|
||||||
|
|
||||||
|
type
|
||||||
|
PERFORMANCE_INFORMATION* {.final.} = object
|
||||||
|
cb*: DWORD
|
||||||
|
CommitTotal: SIZE_T
|
||||||
|
CommitLimit: SIZE_T
|
||||||
|
CommitPeak: SIZE_T
|
||||||
|
PhysicalTotal: SIZE_T
|
||||||
|
PhysicalAvailable: SIZE_T
|
||||||
|
SystemCache: SIZE_T
|
||||||
|
KernelTotal: SIZE_T
|
||||||
|
KernelPaged: SIZE_T
|
||||||
|
KernelNonpaged: SIZE_T
|
||||||
|
PageSize: SIZE_T
|
||||||
|
HandleCount*: DWORD
|
||||||
|
ProcessCount*: DWORD
|
||||||
|
ThreadCount*: DWORD
|
||||||
|
PPERFORMANCE_INFORMATION* = ptr PERFORMANCE_INFORMATION
|
||||||
|
# Skip definition of PERFORMACE_INFORMATION...
|
||||||
|
|
||||||
|
proc GetPerformanceInfo*(pPerformanceInformation: PPERFORMANCE_INFORMATION, cb: DWORD): WINBOOL {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetPerformanceInfo".}
|
||||||
|
|
||||||
|
type
|
||||||
|
ENUM_PAGE_FILE_INFORMATION* {.final.} = object
|
||||||
|
cb*: DWORD
|
||||||
|
Reserved*: DWORD
|
||||||
|
TotalSize: SIZE_T
|
||||||
|
TotalInUse: SIZE_T
|
||||||
|
PeakUsage: SIZE_T
|
||||||
|
PENUM_PAGE_FILE_INFORMATION* = ptr ENUM_PAGE_FILE_INFORMATION
|
||||||
|
|
||||||
|
# Callback procedure
|
||||||
|
type
|
||||||
|
PENUM_PAGE_FILE_CALLBACKW* = proc (pContext: LPVOID, pPageFileInfo: PENUM_PAGE_FILE_INFORMATION, lpFilename: LPCWSTR): WINBOOL{.stdcall.}
|
||||||
|
PENUM_PAGE_FILE_CALLBACKA* = proc (pContext: LPVOID, pPageFileInfo: PENUM_PAGE_FILE_INFORMATION, lpFilename: LPCSTR): WINBOOL{.stdcall.}
|
||||||
|
|
||||||
|
#TODO
|
||||||
|
proc EnumPageFilesA*(pCallBackRoutine: PENUM_PAGE_FILE_CALLBACKA, pContext: LPVOID): WINBOOL {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "EnumPageFilesA".}
|
||||||
|
proc EnumPageFilesW*(pCallBackRoutine: PENUM_PAGE_FILE_CALLBACKW, pContext: LPVOID): WINBOOL {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "EnumPageFilesW".}
|
||||||
|
when defined(winUnicode):
|
||||||
|
proc EnumPageFiles*(pCallBackRoutine: PENUM_PAGE_FILE_CALLBACKW, pContext: LPVOID): WINBOOL {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "EnumPageFilesW".}
|
||||||
|
type PENUM_PAGE_FILE_CALLBACK* = proc (pContext: LPVOID, pPageFileInfo: PENUM_PAGE_FILE_INFORMATION, lpFilename: LPCWSTR): WINBOOL{.stdcall.}
|
||||||
|
else:
|
||||||
|
proc EnumPageFiles*(pCallBackRoutine: PENUM_PAGE_FILE_CALLBACKA, pContext: LPVOID): WINBOOL {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "EnumPageFilesA".}
|
||||||
|
type PENUM_PAGE_FILE_CALLBACK* = proc (pContext: LPVOID, pPageFileInfo: PENUM_PAGE_FILE_INFORMATION, lpFilename: LPCSTR): WINBOOL{.stdcall.}
|
||||||
|
|
||||||
|
proc GetProcessImageFileNameA*(hProcess: HANDLE, lpImageFileName: LPSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetProcessImageFileNameA".}
|
||||||
|
proc GetProcessImageFileNameW*(hProcess: HANDLE, lpImageFileName: LPWSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetProcessImageFileNameW".}
|
||||||
|
when defined(winUnicode):
|
||||||
|
proc GetProcessImageFileName*(hProcess: HANDLE, lpImageFileName: LPWSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetProcessImageFileNameW".}
|
||||||
|
else:
|
||||||
|
proc GetProcessImageFileName*(hProcess: HANDLE, lpImageFileName: LPSTR, nSize: DWORD): DWORD {.stdcall,
|
||||||
|
dynlib: "psapi.dll", importc: "GetProcessImageFileNameA".}
|
||||||
47812
lib/windows/windows.nim
47812
lib/windows/windows.nim
File diff suppressed because it is too large
Load diff
|
|
@ -9,12 +9,12 @@
|
||||||
|
|
||||||
## This module implements Nimrod's support for the ``variant`` datatype.
|
## This module implements Nimrod's support for the ``variant`` datatype.
|
||||||
## `TVariant` shows how the flexibility of dynamic typing is achieved
|
## `TVariant` shows how the flexibility of dynamic typing is achieved
|
||||||
## within a static type system.
|
## within a static type system.
|
||||||
|
|
||||||
type
|
type
|
||||||
TVarType* = enum
|
TVarType* = enum
|
||||||
vtNone,
|
vtNone,
|
||||||
vtBool,
|
vtBool,
|
||||||
vtChar,
|
vtChar,
|
||||||
vtEnum,
|
vtEnum,
|
||||||
vtInt,
|
vtInt,
|
||||||
|
|
@ -31,7 +31,7 @@ type
|
||||||
of vtString: vstring: string
|
of vtString: vstring: string
|
||||||
of vtSet, vtSeq: q: seq[TVariant]
|
of vtSet, vtSeq: q: seq[TVariant]
|
||||||
of vtDict: d: seq[tuple[key, val: TVariant]]
|
of vtDict: d: seq[tuple[key, val: TVariant]]
|
||||||
|
|
||||||
iterator objectFields*[T](x: T, skipInherited: bool): tuple[
|
iterator objectFields*[T](x: T, skipInherited: bool): tuple[
|
||||||
key: string, val: TVariant] {.magic: "ObjectFields"}
|
key: string, val: TVariant] {.magic: "ObjectFields"}
|
||||||
|
|
||||||
|
|
@ -74,10 +74,10 @@ proc `<>`* [T: object](x: T): TVariant {.magic: "ToVariant".}
|
||||||
|
|
||||||
proc `><`*[T](v: TVariant, typ: T): T {.magic: "FromVariant".}
|
proc `><`*[T](v: TVariant, typ: T): T {.magic: "FromVariant".}
|
||||||
|
|
||||||
[<>5, <>67, <>"hallo"]
|
[<>5, <>67, <>"hello"]
|
||||||
myVar><int
|
myVar><int
|
||||||
|
|
||||||
|
|
||||||
proc `==`* (x, y: TVariant): bool =
|
proc `==`* (x, y: TVariant): bool =
|
||||||
if x.vtype == y.vtype:
|
if x.vtype == y.vtype:
|
||||||
case x.vtype
|
case x.vtype
|
||||||
|
|
@ -139,7 +139,7 @@ proc `[]=`* (a, b, c: TVariant) =
|
||||||
a.d[b.vint].val = c
|
a.d[b.vint].val = c
|
||||||
variantError()
|
variantError()
|
||||||
else: variantError()
|
else: variantError()
|
||||||
|
|
||||||
proc `[]`* (a: TVariant, b: int): TVariant {.inline} = return a[<>b]
|
proc `[]`* (a: TVariant, b: int): TVariant {.inline} = return a[<>b]
|
||||||
proc `[]`* (a: TVariant, b: string): TVariant {.inline} = return a[<>b]
|
proc `[]`* (a: TVariant, b: string): TVariant {.inline} = return a[<>b]
|
||||||
proc `[]=`* (a: TVariant, b: int, c: TVariant) {.inline} = a[<>b] = c
|
proc `[]=`* (a: TVariant, b: int, c: TVariant) {.inline} = a[<>b] = c
|
||||||
|
|
@ -154,9 +154,9 @@ proc `+`* (x, y: TVariant): TVariant =
|
||||||
else:
|
else:
|
||||||
case y.vtype
|
case y.vtype
|
||||||
of vtBool, vtChar, vtEnum, vtInt:
|
of vtBool, vtChar, vtEnum, vtInt:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
vint: int64
|
vint: int64
|
||||||
of vtFloat: vfloat: float64
|
of vtFloat: vfloat: float64
|
||||||
of vtString: vstring: string
|
of vtString: vstring: string
|
||||||
|
|
@ -171,11 +171,11 @@ proc `mod`* (x, y: TVariant): TVariant
|
||||||
proc `&`* (x, y: TVariant): TVariant
|
proc `&`* (x, y: TVariant): TVariant
|
||||||
proc `$`* (x: TVariant): string =
|
proc `$`* (x: TVariant): string =
|
||||||
# uses JS notation
|
# uses JS notation
|
||||||
|
|
||||||
proc parseVariant*(s: string): TVariant
|
proc parseVariant*(s: string): TVariant
|
||||||
proc `<`* (x, y: TVariant): bool
|
proc `<`* (x, y: TVariant): bool
|
||||||
proc `<=`* (x, y: TVariant): bool
|
proc `<=`* (x, y: TVariant): bool
|
||||||
|
|
||||||
proc hash*(x: TVariant): int =
|
proc hash*(x: TVariant): int =
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ proc addChar(s: NimString, c: char): NimString {.compilerProc.} =
|
||||||
|
|
||||||
# These routines should be used like following:
|
# These routines should be used like following:
|
||||||
# <Nimrod code>
|
# <Nimrod code>
|
||||||
# s &= "hallo " & name & " how do you feel?"
|
# s &= "Hello " & name & ", how do you feel?"
|
||||||
#
|
#
|
||||||
# <generated C code>
|
# <generated C code>
|
||||||
# {
|
# {
|
||||||
|
|
@ -115,7 +115,7 @@ proc addChar(s: NimString, c: char): NimString {.compilerProc.} =
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
# <Nimrod code>
|
# <Nimrod code>
|
||||||
# s = "hallo " & name & " how do you feel?"
|
# s = "Hello " & name & ", how do you feel?"
|
||||||
#
|
#
|
||||||
# <generated C code>
|
# <generated C code>
|
||||||
# {
|
# {
|
||||||
|
|
@ -180,8 +180,8 @@ proc incrSeq(seq: PGenericSeq, elemSize: int): PGenericSeq {.compilerProc.} =
|
||||||
result = cast[PGenericSeq](newSeq(extGetCellType(seq), s))
|
result = cast[PGenericSeq](newSeq(extGetCellType(seq), s))
|
||||||
genericSeqAssign(result, seq, XXX)
|
genericSeqAssign(result, seq, XXX)
|
||||||
#copyMem(result, seq, seq.len * elemSize + GenericSeqSize)
|
#copyMem(result, seq, seq.len * elemSize + GenericSeqSize)
|
||||||
inc(result.len)
|
inc(result.len)
|
||||||
else:
|
else:
|
||||||
result = seq
|
result = seq
|
||||||
if result.len >= result.space:
|
if result.len >= result.space:
|
||||||
result.space = resize(result.space)
|
result.space = resize(result.space)
|
||||||
|
|
@ -214,7 +214,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
|
||||||
# we need to decref here, otherwise the GC leaks!
|
# we need to decref here, otherwise the GC leaks!
|
||||||
when not defined(boehmGC) and not defined(nogc):
|
when not defined(boehmGC) and not defined(nogc):
|
||||||
for i in newLen..result.len-1:
|
for i in newLen..result.len-1:
|
||||||
forAllChildrenAux(cast[pointer](cast[TAddress](result) +%
|
forAllChildrenAux(cast[pointer](cast[TAddress](result) +%
|
||||||
GenericSeqSize +% (i*%elemSize)),
|
GenericSeqSize +% (i*%elemSize)),
|
||||||
extGetCellType(result).base, waZctDecRef)
|
extGetCellType(result).base, waZctDecRef)
|
||||||
# and set the memory to nil:
|
# and set the memory to nil:
|
||||||
|
|
|
||||||
1070
rod/ccgexprs.nim
1070
rod/ccgexprs.nim
File diff suppressed because it is too large
Load diff
|
|
@ -1,3 +1,3 @@
|
||||||
# Simplest Nimrod program
|
# Simplest Nimrod program
|
||||||
|
|
||||||
echo "Hallo, World!"
|
echo "Hello, World!"
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ macrotest(stdout)
|
||||||
#GC_disable()
|
#GC_disable()
|
||||||
|
|
||||||
echo("This was compiled by Nimrod version " & system.nimrodVersion)
|
echo("This was compiled by Nimrod version " & system.nimrodVersion)
|
||||||
writeln(stdout, "Hallo", " World", "!")
|
writeln(stdout, "Hello", " World", "!")
|
||||||
|
|
||||||
echo(["a", "b", "c", "d"].len)
|
echo(["a", "b", "c", "d"].len)
|
||||||
for x in items(["What's", "your", "name", "?", ]):
|
for x in items(["What's", "your", "name", "?", ]):
|
||||||
|
|
@ -51,7 +51,7 @@ var testseq: seq[string] = @[
|
||||||
]
|
]
|
||||||
echo(repr(testseq))
|
echo(repr(testseq))
|
||||||
|
|
||||||
var dummy = "hallo"
|
var dummy = "hello"
|
||||||
echo(copy(dummy, 2, 3))
|
echo(copy(dummy, 2, 3))
|
||||||
|
|
||||||
echo($meC)
|
echo($meC)
|
||||||
|
|
@ -60,11 +60,11 @@ echo($meC)
|
||||||
for x, y in items([(1, 2), (3, 4), (6, 1), (5, 2)]):
|
for x, y in items([(1, 2), (3, 4), (6, 1), (5, 2)]):
|
||||||
echo x
|
echo x
|
||||||
echo y
|
echo y
|
||||||
|
|
||||||
proc simpleConst(): int = return 34
|
proc simpleConst(): int = return 34
|
||||||
|
|
||||||
# test constant evaluation:
|
# test constant evaluation:
|
||||||
const
|
const
|
||||||
constEval3 = simpleConst()
|
constEval3 = simpleConst()
|
||||||
constEval = "abc".contains('b')
|
constEval = "abc".contains('b')
|
||||||
constEval2 = fac(7)
|
constEval2 = fac(7)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# test the file-IO
|
# test the file-IO
|
||||||
|
|
||||||
proc main() =
|
proc main() =
|
||||||
for line in lines("thallo.nim"):
|
for line in lines("thello.nim"):
|
||||||
writeln(stdout, line)
|
writeln(stdout, line)
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ proc Foo(n: int): int =
|
||||||
while b:
|
while b:
|
||||||
a = a + 3
|
a = a + 3
|
||||||
a = a + 5
|
a = a + 5
|
||||||
write(stdout, "Hallo!")
|
write(stdout, "Hello!")
|
||||||
|
|
||||||
|
|
||||||
# We should come till here :-)
|
# We should come till here :-)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,6 @@ import streams
|
||||||
|
|
||||||
var outp = newFileStream(stdout)
|
var outp = newFileStream(stdout)
|
||||||
var inp = newFileStream(stdin)
|
var inp = newFileStream(stdin)
|
||||||
write(outp, "Hallo! What is your name?")
|
write(outp, "Hello! What is your name?")
|
||||||
var line = readLine(inp)
|
var line = readLine(inp)
|
||||||
write(outp, "nice name: " & line)
|
write(outp, "Nice name: " & line)
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
# Test the new initialization for modules
|
# Test the new initialization for modules
|
||||||
write(stdout, "Hallo from module! ")
|
write(stdout, "Hello from module! ")
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import tbintree
|
||||||
|
|
||||||
var
|
var
|
||||||
root: PBinaryTree[string]
|
root: PBinaryTree[string]
|
||||||
x = newNode("hallo")
|
x = newNode("hello")
|
||||||
add(root, x)
|
add(root, x)
|
||||||
add(root, "world")
|
add(root, "world")
|
||||||
if find(root, "world"):
|
if find(root, "world"):
|
||||||
|
|
@ -21,5 +21,5 @@ add(r2, 99)
|
||||||
for y in items(r2):
|
for y in items(r2):
|
||||||
stdout.write(y)
|
stdout.write(y)
|
||||||
|
|
||||||
#OUT halloworld99110223
|
#OUT helloworld99110223
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,12 @@ proc add*[Ty](root: var PBinaryTree[Ty], data: Ty) =
|
||||||
# convenience proc:
|
# convenience proc:
|
||||||
add(root, newNode(data))
|
add(root, newNode(data))
|
||||||
|
|
||||||
proc find*[Ty2](b: PBinaryTree[Ty2], data: Ty2): bool =
|
proc find*[Ty2](b: PBinaryTree[Ty2], data: Ty2): bool =
|
||||||
# for testing this needs to be recursive, so that the
|
# for testing this needs to be recursive, so that the
|
||||||
# instantiated type is checked for proper tyGenericInst envelopes
|
# instantiated type is checked for proper tyGenericInst envelopes
|
||||||
if b == nil:
|
if b == nil:
|
||||||
result = false
|
result = false
|
||||||
else:
|
else:
|
||||||
var c = cmp(data, b.data)
|
var c = cmp(data, b.data)
|
||||||
if c < 0: result = find(b.le, data)
|
if c < 0: result = find(b.le, data)
|
||||||
elif c > 0: result = find(b.ri, data)
|
elif c > 0: result = find(b.ri, data)
|
||||||
|
|
@ -66,7 +66,7 @@ iterator items*[T](root: PBinaryTree[T]): T =
|
||||||
while n != nil:
|
while n != nil:
|
||||||
add(stack, n)
|
add(stack, n)
|
||||||
n = n.le
|
n = n.le
|
||||||
if stack.len > 0:
|
if stack.len > 0:
|
||||||
n = stack.pop()
|
n = stack.pop()
|
||||||
yield n.data
|
yield n.data
|
||||||
n = n.ri
|
n = n.ri
|
||||||
|
|
@ -81,7 +81,7 @@ proc debug[T](a: PBinaryTree[T]) =
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
var
|
var
|
||||||
root: PBinaryTree[string]
|
root: PBinaryTree[string]
|
||||||
x = newNode("hallo")
|
x = newNode("hello")
|
||||||
add(root, x)
|
add(root, x)
|
||||||
add(root, "world")
|
add(root, "world")
|
||||||
if find(root, "world"):
|
if find(root, "world"):
|
||||||
|
|
@ -89,7 +89,7 @@ when isMainModule:
|
||||||
stdout.write(str)
|
stdout.write(str)
|
||||||
else:
|
else:
|
||||||
stdout.writeln("BUG")
|
stdout.writeln("BUG")
|
||||||
|
|
||||||
var
|
var
|
||||||
r2: PBinaryTree[int]
|
r2: PBinaryTree[int]
|
||||||
add(r2, newNode(110))
|
add(r2, newNode(110))
|
||||||
|
|
@ -98,4 +98,4 @@ when isMainModule:
|
||||||
for y in items(r2):
|
for y in items(r2):
|
||||||
stdout.write(y)
|
stdout.write(y)
|
||||||
|
|
||||||
#OUT halloworld99110223
|
#OUT helloworld99110223
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,5 @@
|
||||||
|
|
||||||
import minit
|
import minit
|
||||||
|
|
||||||
write(stdout, "Hallo from main module!\n")
|
write(stdout, "Hello from main module!\n")
|
||||||
#OUT Hallo from module! Hallo from main module!
|
#OUT Hello from module! Hello from main module!
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,5 @@
|
||||||
proc write(t: TFile, s: string) =
|
proc write(t: TFile, s: string) =
|
||||||
nil # a nop
|
nil # a nop
|
||||||
|
|
||||||
system.write(stdout, "hallo")
|
system.write(stdout, "hello")
|
||||||
#OUT hallo
|
#OUT hello
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ proc mypos(sub, s: string, start: int = 0): int =
|
||||||
else:
|
else:
|
||||||
result = -1
|
result = -1
|
||||||
|
|
||||||
var sub = "hallo"
|
var sub = "hello"
|
||||||
var s = "world hallo"
|
var s = "world hello"
|
||||||
write(stdout, mypos(sub, s))
|
write(stdout, mypos(sub, s))
|
||||||
#OUT 6
|
#OUT 6
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import strutils
|
import strutils
|
||||||
|
|
||||||
var x = "hallo world!".toLower.toUpper
|
var x = "hello world!".toLower.toUpper
|
||||||
x.echo()
|
x.echo()
|
||||||
#OUT HALLO WORLD!
|
#OUT HELLO WORLD!
|
||||||
|
|
||||||
|
|
|
||||||
10
tests/tenuminh.nim
Normal file
10
tests/tenuminh.nim
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
type
|
||||||
|
TCardPts = enum
|
||||||
|
North, West, South, East
|
||||||
|
|
||||||
|
TCardPts2 = enum of TCardPts
|
||||||
|
N, W, S, E
|
||||||
|
|
||||||
|
# If I do:
|
||||||
|
var y = W
|
||||||
|
echo($y & "=" & $ord(y)) #OUT W=5
|
||||||
Loading…
Add table
Add a link
Reference in a new issue