tester should work again; documented (;)
This commit is contained in:
parent
e70cc64e90
commit
427f84b4ec
4 changed files with 43 additions and 7 deletions
|
|
@ -214,12 +214,12 @@ proc genConstStmt(p: BProc, t: PNode) =
|
||||||
|
|
||||||
proc genIfStmt(p: BProc, n: PNode) =
|
proc genIfStmt(p: BProc, n: PNode) =
|
||||||
#
|
#
|
||||||
# if (!expr1) goto L1;
|
# { if (!expr1) goto L1;
|
||||||
# { thenPart }
|
# thenPart }
|
||||||
# goto LEnd
|
# goto LEnd
|
||||||
# L1:
|
# L1:
|
||||||
# if (!expr2) goto L2;
|
# { if (!expr2) goto L2;
|
||||||
# { thenPart2 }
|
# thenPart2 }
|
||||||
# goto LEnd
|
# goto LEnd
|
||||||
# L2:
|
# L2:
|
||||||
# { elsePart }
|
# { elsePart }
|
||||||
|
|
@ -232,13 +232,15 @@ proc genIfStmt(p: BProc, n: PNode) =
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
var it = n.sons[i]
|
var it = n.sons[i]
|
||||||
if it.len == 2:
|
if it.len == 2:
|
||||||
|
startBlock(p)
|
||||||
initLocExpr(p, it.sons[0], a)
|
initLocExpr(p, it.sons[0], a)
|
||||||
Lelse = getLabel(p)
|
Lelse = getLabel(p)
|
||||||
inc(p.labels)
|
inc(p.labels)
|
||||||
lineFF(p, cpsStmts, "if (!$1) goto $2;$n",
|
lineFF(p, cpsStmts, "if (!$1) goto $2;$n",
|
||||||
"br i1 $1, label %LOC$3, label %$2$n" & "LOC$3: $n",
|
"br i1 $1, label %LOC$3, label %$2$n" & "LOC$3: $n",
|
||||||
[rdLoc(a), Lelse, toRope(p.labels)])
|
[rdLoc(a), Lelse, toRope(p.labels)])
|
||||||
genSimpleBlock(p, it.sons[1])
|
genStmts(p, it.sons[1])
|
||||||
|
endBlock(p)
|
||||||
if sonsLen(n) > 1:
|
if sonsLen(n) > 1:
|
||||||
lineFF(p, cpsStmts, "goto $1;$n", "br label %$1$n", [Lend])
|
lineFF(p, cpsStmts, "goto $1;$n", "br label %$1$n", [Lend])
|
||||||
fixLabel(p, Lelse)
|
fixLabel(p, Lelse)
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,9 @@ The language constructs are explained using an extended BNF, in
|
||||||
which ``(a)*`` means 0 or more ``a``'s, ``a+`` means 1 or more ``a``'s, and
|
which ``(a)*`` means 0 or more ``a``'s, ``a+`` means 1 or more ``a``'s, and
|
||||||
``(a)?`` means an optional *a*. Parentheses may be used to group elements.
|
``(a)?`` means an optional *a*. Parentheses may be used to group elements.
|
||||||
|
|
||||||
|
``&`` is the lookahead operator; ``&a`` means that an ``a`` is expected but
|
||||||
|
not consumed. It will be consumed in the following rule.
|
||||||
|
|
||||||
The ``|``, ``/`` symbols are used to mark alternatives and have the lowest
|
The ``|``, ``/`` symbols are used to mark alternatives and have the lowest
|
||||||
precedence. ``/`` is the ordered choice that requires the parser to try the
|
precedence. ``/`` is the ordered choice that requires the parser to try the
|
||||||
alternatives in the given order. ``/`` is often used to ensure the grammar
|
alternatives in the given order. ``/`` is often used to ensure the grammar
|
||||||
|
|
@ -1726,6 +1729,17 @@ contain other statements. To avoid the `dangling else problem`:idx:, complex
|
||||||
statements always have to be intended. The details can be found in the grammar.
|
statements always have to be intended. The details can be found in the grammar.
|
||||||
|
|
||||||
|
|
||||||
|
Statement list expression
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
Statements can also occur in an expression context that looks
|
||||||
|
like ``(stmt1; stmt2; ...; ex)``. This is called
|
||||||
|
an `statement list expression`:idx: or ``(;)``. The type
|
||||||
|
of ``(stmt1; stmt2; ...; ex)`` is the type of ``ex``. All the other statements
|
||||||
|
must be of type ``void``. (One can use ``discard`` to produce a ``void`` type.)
|
||||||
|
``(;)`` does not introduce a new scope.
|
||||||
|
|
||||||
|
|
||||||
Discard statement
|
Discard statement
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
|
@ -1892,6 +1906,20 @@ the ``:`` are executed. This goes on until the last ``elif``. If all
|
||||||
conditions fail, the ``else`` part is executed. If there is no ``else``
|
conditions fail, the ``else`` part is executed. If there is no ``else``
|
||||||
part, execution continues with the statement after the ``if`` statement.
|
part, execution continues with the statement after the ``if`` statement.
|
||||||
|
|
||||||
|
The scoping for an ``if`` statement is slightly subtle to support an important
|
||||||
|
use case. A new scope starts for the ``if``/``elif`` condition and ends after
|
||||||
|
the corresponding *then* block:
|
||||||
|
|
||||||
|
.. code-block:: nimrod
|
||||||
|
if {| (let m = input =~ re"(\w+)=\w+"; m.isMatch):
|
||||||
|
echo "key ", m[0], " value ", m[1] |}
|
||||||
|
elif {| (let m = input =~ re""; m.isMatch):
|
||||||
|
echo "new m in this scope" |}
|
||||||
|
else:
|
||||||
|
# 'm' not declared here
|
||||||
|
|
||||||
|
In the example the scopes have been enclosed in ``{| |}``.
|
||||||
|
|
||||||
|
|
||||||
Case statement
|
Case statement
|
||||||
--------------
|
--------------
|
||||||
|
|
|
||||||
|
|
@ -515,6 +515,13 @@ contain indentation at certain places for better readability:
|
||||||
As a rule of thumb, indentation within expressions is allowed after operators,
|
As a rule of thumb, indentation within expressions is allowed after operators,
|
||||||
an open parenthesis and after commas.
|
an open parenthesis and after commas.
|
||||||
|
|
||||||
|
With parenthesis and semicolons ``(;)`` you can use statements where only
|
||||||
|
an expression is allowed:
|
||||||
|
|
||||||
|
.. code-block:: nimrod
|
||||||
|
# computes fac(4) at compile time:
|
||||||
|
const fac4 = (var x = 1; for i in 1..4: x *= i; x)
|
||||||
|
|
||||||
|
|
||||||
Procedures
|
Procedures
|
||||||
==========
|
==========
|
||||||
|
|
|
||||||
3
todo.txt
3
todo.txt
|
|
@ -7,8 +7,6 @@ version 0.9.2
|
||||||
- acyclic vs prunable; introduce GC hints
|
- acyclic vs prunable; introduce GC hints
|
||||||
- CGEN: ``restrict`` pragma + backend support; computed goto support
|
- CGEN: ``restrict`` pragma + backend support; computed goto support
|
||||||
- document NimMain and check whether it works for threading
|
- document NimMain and check whether it works for threading
|
||||||
- parser/grammar:
|
|
||||||
* document (var x = 12; for i in ... ; x) construct
|
|
||||||
- make use of commonType relation in expressions
|
- make use of commonType relation in expressions
|
||||||
- further expr/stmt unification:
|
- further expr/stmt unification:
|
||||||
- rewrite nkCaseExpr handling
|
- rewrite nkCaseExpr handling
|
||||||
|
|
@ -59,6 +57,7 @@ version 0.9.X
|
||||||
- improve the compiler as a service
|
- improve the compiler as a service
|
||||||
- better support for macros that rewrite procs
|
- better support for macros that rewrite procs
|
||||||
- macros need access to types and symbols (partially implemented)
|
- macros need access to types and symbols (partially implemented)
|
||||||
|
- effect propagation for callbacks
|
||||||
- perhaps: change comment handling in the AST
|
- perhaps: change comment handling in the AST
|
||||||
- enforce 'simpleExpr' more often --> doesn't work; tkProc is
|
- enforce 'simpleExpr' more often --> doesn't work; tkProc is
|
||||||
part of primary!
|
part of primary!
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue