implemented 'let' statement

This commit is contained in:
Araq 2011-11-29 17:27:48 +01:00
commit 7fcbdc6d42
33 changed files with 169 additions and 103 deletions

View file

@ -1555,7 +1555,6 @@ variables of the same type:
If an initializer is given the type can be omitted: the variable is then of the
same type as the initializing expression. Variables are always initialized
with a default value if there is no initializing expression. The default
value depends on the type and is always a zero in binary.
@ -1586,6 +1585,19 @@ The implicit initialization can be avoided for optimization reasons with the
a {.noInit.}: array [0..1023, char]
let statement
~~~~~~~~~~~~~
A `Let`:idx: statement declares new local and global `single assignment`:idx:
variables and binds a value to them. The syntax is the of the ``var``
statement, except that the keyword ``var`` is replaced by the keyword ``let``.
Let variables are not l-values and can thus not be passed to ``var`` parameters
nor can their address be taken. They cannot be assigned new values.
For let variables the same pragmas are available as for ordinary variables.
Const section
~~~~~~~~~~~~~

View file

@ -213,6 +213,17 @@ constants:
z = y + 5 # computations are possible
The let statement
=================
The ``let`` statement works like the ``var`` statement but the declared
symbols are *single assignment* variables: After the initialization their
value cannot change:
.. code-block::
let x = "abc" # introduces a new variable `x` and binds a value to it
x = "xyz" # Illegal: assignment to `x`
Control flow statements
=======================
@ -227,7 +238,7 @@ If statement
The if statement is one way to branch the control flow:
.. code-block:: nimrod
var name = readLine(stdin)
let name = readLine(stdin)
if name == "":
echo("Poor soul, you lost your name?")
elif name == "name":
@ -247,7 +258,7 @@ Another way to branch is provided by the case statement. A case statement is
a multi-branch:
.. code-block:: nimrod
var name = readLine(stdin)
let name = readLine(stdin)
case name
of "":
echo("Poor soul, you lost your name?")
@ -270,7 +281,7 @@ For integers or other ordinal types value ranges are also possible:
from strutils import parseInt
Echo("A number please: ")
var n = parseInt(readLine(stdin))
let n = parseInt(readLine(stdin))
case n
of 0..2, 4..7: Echo("The number is in the set: {0, 1, 2, 4, 5, 6, 7}")
of 3, 8: Echo("The number is 3 or 8")
@ -410,7 +421,7 @@ the next iteration immediately:
.. code-block:: nimrod
while true:
var x = readLine(stdin)
let x = readLine(stdin)
if x == "": continue
Echo(x)
@ -717,8 +728,8 @@ However, this cannot be done for mutually recursive procedures:
Here ``odd`` depends on ``even`` and vice versa. Thus ``even`` needs to be
introduced to the compiler before it is completely defined. The syntax for
such a `forward declaration` is simple: just omit the ``=`` and the procedure's
body.
such a `forward declaration`:idx: is simple: just omit the ``=`` and the
procedure's body.
Iterators
@ -846,7 +857,7 @@ to mark them to be of another integer type:
.. code-block:: nimrod
var
let
x = 0 # x is of type ``int``
y = 0'i8 # y is of type ``int8``
z = 0'i64 # z is of type ``int64``

View file

@ -580,13 +580,13 @@ via a special ``:`` syntax:
.. code-block:: nimrod
template withFile(f: expr, filename: string, mode: TFileMode,
actions: stmt): stmt =
body: stmt): stmt =
block:
var fn = filename
let fn = filename
var f: TFile
if open(f, fn, mode):
try:
actions
body
finally:
close(f)
else:
@ -596,10 +596,10 @@ via a special ``:`` syntax:
txt.writeln("line 1")
txt.writeln("line 2")
In the example the two ``writeln`` statements are bound to the ``actions``
In the example the two ``writeln`` statements are bound to the ``body``
parameter. The ``withFile`` template contains boilerplate code and helps to
avoid a common bug: to forget to close the file. Note how the
``var fn = filename`` statement ensures that ``filename`` is evaluated only
``let fn = filename`` statement ensures that ``filename`` is evaluated only
once.