summary refs log tree commit diff stats
path: root/doc
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-05-25 21:20:26 +0200
committerAraq <rumpf_a@web.de>2014-05-25 21:20:26 +0200
commit04a1555f4aa90eadc4d974a04abbf50d1e8b7134 (patch)
tree2e26496b1158a1b14c8c0bb307c670ea2d100cb5 /doc
parentb230303fd6dd1d593aecf792ee8f72552e7e5946 (diff)
parent1d6c05edc399e31919114f2b07519ae79ae1b804 (diff)
downloadNim-04a1555f4aa90eadc4d974a04abbf50d1e8b7134.tar.gz
Merge branch 'devel' of https://github.com/Araq/Nimrod into devel
Diffstat (limited to 'doc')
-rw-r--r--doc/abstypes.txt152
-rw-r--r--doc/lib.txt2
-rw-r--r--doc/manual.txt85
-rw-r--r--doc/nimrodc.txt2
4 files changed, 81 insertions, 160 deletions
diff --git a/doc/abstypes.txt b/doc/abstypes.txt
deleted file mode 100644
index c5827745a..000000000
--- a/doc/abstypes.txt
+++ /dev/null
@@ -1,152 +0,0 @@
-==============
-Abstract types
-==============
-
-.. contents::
-
-Abstract types in Nimrod provide a means to model different `units`:idx: of
-a `base type`:idx:.
-
-
-Use case 1: SQL strings
------------------------
-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
-values is vulnerable to the famous `SQL injection attack`:idx:\:
-
-.. code-block:: nimrod
-  proc query(db: TDbHandle, statement: TSQL) = ...
-
-  var
-    username: string
-
-  db.query("SELECT FROM users WHERE name = '$1'" % username)
-  # Horrible security hole, but the compiler does not mind!
-
-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
-``TSQL`` that is incompatible with ``string``:
-
-.. code-block:: nimrod
-  type
-    TSQL = abstract string
-
-  proc query(db: TDbHandle, statement: TSQL) = ...
-
-  var
-    username: string
-
-  db.query("SELECT FROM users WHERE name = '$1'" % username)
-  # Error at compile time: `query` expects an SQL string!
-
-
-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
-conversions from ``string`` to ``TSQL`` are allowed:
-
-.. code-block:: nimrod
-  proc properQuote(s: string): TSQL =
-    # quotes a string properly for an SQL statement
-    ...
-
-  proc `%` (frmt: TSQL, values: openarray[string]): TSQL =
-    # quote each argument:
-    var v = values.each(properQuote)
-    # we need a temporary type for the type conversion :-(
-    type TStrSeq = seq[string]
-    # call strutils.`%`:
-    result = TSQL(string(frmt) % TStrSeq(v))
-
-  db.query("SELECT FROM users WHERE name = $1".TSQL % username)
-
-Now we have compile-time checking against SQL injection attacks.
-Since ``"".TSQL`` is transformed to ``TSQL("")`` no new syntax is needed
-for nice looking ``TSQL`` string literals.
-
-
-
-Use case 2: Money
------------------
-Different currencies should not be mixed in monetary calculations. Abstract
-types are a perfect tool to model different currencies:
-
-.. code-block:: nimrod
-  type
-    TDollar = abstract int
-    TEuro = abstract int
-
-  var
-    d: TDollar
-    e: TEuro
-
-  echo d + 12
-  # Error: cannot add a number with no unit with a ``TDollar``
-
-Unfortunetaly, ``d + 12.TDollar`` is not allowed either,
-because ``+`` is defined for ``int`` (among others), not for ``TDollar``. So
-we define our own ``+`` for dollars:
-
-.. code-block::
-  proc `+` (x, y: TDollar): TDollar =
-    result = TDollar(int(x) + int(y))
-
-It does not make sense to multiply a dollar with a dollar, but with a
-number without unit; and the same holds for division:
-
-.. code-block::
-  proc `*` (x: TDollar, y: int): TDollar =
-    result = TDollar(int(x) * y)
-
-  proc `*` (x: int, y: TDollar): TDollar =
-    result = TDollar(x * int(y))
-
-  proc `div` ...
-
-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
-``+`` for dollars should produce the same binary code as ``+`` for ints.
-The pragma ``borrow`` has been designed to solve this problem; in principle
-it generates the trivial implementation for us:
-
-.. code-block:: nimrod
-  proc `*` (x: TDollar, y: int): TDollar {.borrow.}
-  proc `*` (x: int, y: TDollar): TDollar {.borrow.}
-  proc `div` (x: TDollar, y: int): TDollar {.borrow.}
-
-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
-generated.
-
-But it seems we still have to repeat all this boilerplate code for
-the ``TEuro`` currency. Fortunately, Nimrod has a template mechanism:
-
-.. code-block:: nimrod
-  template Additive(typ: typeDesc): stmt =
-    proc `+` *(x, y: typ): typ {.borrow.}
-    proc `-` *(x, y: typ): typ {.borrow.}
-
-    # unary operators:
-    proc `+` *(x: typ): typ {.borrow.}
-    proc `-` *(x: typ): typ {.borrow.}
-
-  template Multiplicative(typ, base: typeDesc): stmt =
-    proc `*` *(x: typ, y: base): typ {.borrow.}
-    proc `*` *(x: base, y: typ): typ {.borrow.}
-    proc `div` *(x: typ, y: base): typ {.borrow.}
-    proc `mod` *(x: typ, y: base): typ {.borrow.}
-
-  template Comparable(typ: typeDesc): stmt =
-    proc `<` * (x, y: typ): bool {.borrow.}
-    proc `<=` * (x, y: typ): bool {.borrow.}
-    proc `==` * (x, y: typ): bool {.borrow.}
-
-  template DefineCurrency(typ, base: expr): stmt =
-    type
-      typ* = abstract base
-    Additive(typ)
-    Multiplicative(typ, base)
-    Comparable(typ)
-
-  DefineCurrency(TDollar, int)
-  DefineCurrency(TEuro, int)
-
diff --git a/doc/lib.txt b/doc/lib.txt
index 3ca519c9e..2da753007 100644
--- a/doc/lib.txt
+++ b/doc/lib.txt
@@ -535,7 +535,7 @@ Database support
 * `odbcsql <odbcsql.html>`_
   interface to the ODBC driver.
 * `sphinx <sphinx.html>`_
-  Nimrod wrapper for ``shpinx``.
+  Nimrod wrapper for ``sphinx``.
 
 
 XML Processing
diff --git a/doc/manual.txt b/doc/manual.txt
index 39e2bad2a..a87abab7a 100644
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -123,7 +123,7 @@ This means that all the control structures are recognized by indentation.
 Indentation consists only of spaces; tabulators are not allowed.
 
 The indentation handling is implemented as follows: The lexer annotates the
-following token with the preceeding number of spaces; indentation is not
+following token with the preceding number of spaces; indentation is not
 a separate token. This trick allows parsing of Nimrod with only 1 token of
 lookahead.
 
@@ -617,7 +617,7 @@ Ordinal types
 
 Integers, bool, characters and enumeration types (and subranges of these
 types) belong to ordinal types. For reasons of simplicity of implementation
-the types ``uint`` and ``uint64`` are no ordinal types.
+the types ``uint`` and ``uint64`` are not ordinal types.
 
 
 Pre-defined integer types
@@ -686,7 +686,7 @@ kinds of integer types are used: the smaller type is converted to the larger.
 A `narrowing type conversion`:idx: converts a larger to a smaller type (for
 example ``int32 -> int16``. A `widening type conversion`:idx: converts a 
 smaller type to a larger type (for example ``int16 -> int32``). In Nimrod only
-widening type conversion are *implicit*:
+widening type conversions are *implicit*:
 
 .. code-block:: nimrod
   var myInt16 = 5i16
@@ -965,6 +965,14 @@ stack roots conservatively. One can use the builtin procs ``GC_ref`` and
 ``GC_unref`` to keep the string data alive for the rare cases where it does
 not work.
 
+A `$` proc is defined for cstrings that returns a string. Thus to get a nimrod
+string from a cstring:
+
+.. code-block:: nimrod
+  var str: string = "Hello!"
+  var cstr: cstring = s
+  var newstr: string = $cstr
+
 
 Structured types
 ----------------
@@ -1519,7 +1527,7 @@ Most calling conventions exist only for the Windows 32-bit platform.
 
 Assigning/passing a procedure to a procedural variable is only allowed if one
 of the following conditions hold:
-1) The procedure that is accessed resists in the current module.
+1) The procedure that is accessed resides in the current module.
 2) The procedure is marked with the ``procvar`` pragma (see `procvar pragma`_).
 3) The procedure has a calling convention that differs from ``nimcall``.
 4) The procedure is anonymous.
@@ -1527,8 +1535,8 @@ of the following conditions hold:
 The rules' purpose is to prevent the case that extending a non-``procvar`` 
 procedure with default parameters breaks client code.
 
-The default calling convention is ``nimcall``, unless it is an inner proc (
-a proc inside of a proc). For an inner proc an analysis is performed whether it
+The default calling convention is ``nimcall``, unless it is an inner proc (a
+proc inside of a proc). For an inner proc an analysis is performed whether it
 accesses its environment. If it does so, it has the calling convention
 ``closure``, otherwise it has the calling convention ``nimcall``.
 
@@ -1542,6 +1550,10 @@ of a distinct type that it **does not** imply a subtype relation between it
 and its base type. Explicit type conversions from a distinct type to its
 base type and vice versa are allowed.
 
+
+Modelling currencies
+~~~~~~~~~~~~~~~~~~~~
+
 A distinct type can be used to model different physical `units`:idx: with a
 numerical base type, for example. The following example models currencies.
 
@@ -1649,6 +1661,67 @@ certain builtin operations to be lifted:
 Currently only the dot accessor can be borrowed in this way.
 
 
+Avoiding SQL injection attacks
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+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
+values is vulnerable to the famous `SQL injection attack`:idx:\:
+
+.. code-block:: nimrod
+  import strutils
+
+  proc query(db: TDbHandle, statement: string) = ...
+
+  var
+    username: string
+
+  db.query("SELECT FROM users WHERE name = '$1'" % username)
+  # Horrible security hole, but the compiler does not mind!
+
+This can be avoided by distinguishing strings that contain SQL from strings
+that don't. Distinct types provide a means to introduce a new string type
+``TSQL`` that is incompatible with ``string``:
+
+.. code-block:: nimrod
+  type
+    TSQL = distinct string
+
+  proc query(db: TDbHandle, statement: TSQL) = ...
+
+  var
+    username: string
+
+  db.query("SELECT FROM users WHERE name = '$1'" % username)
+  # Error at compile time: `query` expects an SQL string!
+
+
+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
+conversions from ``string`` to ``TSQL`` are allowed:
+
+.. code-block:: nimrod
+  import strutils, sequtils
+
+  proc properQuote(s: string): TSQL =
+    # quotes a string properly for an SQL statement
+    return TSQL(s)
+
+  proc `%` (frmt: TSQL, values: openarray[string]): TSQL =
+    # quote each argument:
+    let v = values.mapIt(TSQL, properQuote(it))
+    # we need a temporary type for the type conversion :-(
+    type TStrSeq = seq[string]
+    # call strutils.`%`:
+    result = TSQL(string(frmt) % TStrSeq(v))
+
+  db.query("SELECT FROM users WHERE name = '$1'".TSQL % [username])
+
+Now we have compile-time checking against SQL injection attacks.  Since
+``"".TSQL`` is transformed to ``TSQL("")`` no new syntax is needed for nice
+looking ``TSQL`` string literals. The hypothetical ``TSQL`` type actually
+exists in the library as the `TSqlQuery type <db_sqlite.html#TSqlQuery>`_ of
+modules like `db_sqlite <db_sqlite.html>`_.
 
 
 Void type
diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt
index 52e0a6eaf..d1925547e 100644
--- a/doc/nimrodc.txt
+++ b/doc/nimrodc.txt
@@ -167,7 +167,7 @@ might contain some cruft even when dead code elimination is turned on. So
 the final release build should be done with ``--symbolFiles:off``.

 

 Due to the aggregation of C code it is also recommended that each project

-resists in its own directory so that the generated ``nimcache`` directory

+resides in its own directory so that the generated ``nimcache`` directory

 is not shared between different projects.