diff options
-rw-r--r-- | compiler/ccgstmts.nim | 12 | ||||
-rw-r--r-- | doc/manual.txt | 28 | ||||
-rw-r--r-- | doc/tut1.txt | 7 | ||||
-rw-r--r-- | todo.txt | 3 |
4 files changed, 43 insertions, 7 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 1f0ffd656..5fc06edfb 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -214,12 +214,12 @@ proc genConstStmt(p: BProc, t: PNode) = proc genIfStmt(p: BProc, n: PNode) = # - # if (!expr1) goto L1; - # { thenPart } + # { if (!expr1) goto L1; + # thenPart } # goto LEnd # L1: - # if (!expr2) goto L2; - # { thenPart2 } + # { if (!expr2) goto L2; + # thenPart2 } # goto LEnd # L2: # { elsePart } @@ -232,13 +232,15 @@ proc genIfStmt(p: BProc, n: PNode) = for i in countup(0, sonsLen(n) - 1): var it = n.sons[i] if it.len == 2: + startBlock(p) initLocExpr(p, it.sons[0], a) Lelse = getLabel(p) inc(p.labels) lineFF(p, cpsStmts, "if (!$1) goto $2;$n", "br i1 $1, label %LOC$3, label %$2$n" & "LOC$3: $n", [rdLoc(a), Lelse, toRope(p.labels)]) - genSimpleBlock(p, it.sons[1]) + genStmts(p, it.sons[1]) + endBlock(p) if sonsLen(n) > 1: lineFF(p, cpsStmts, "goto $1;$n", "br label %$1$n", [Lend]) fixLabel(p, Lelse) diff --git a/doc/manual.txt b/doc/manual.txt index 3437e3e44..2cbf50f2c 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -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 ``(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 precedence. ``/`` is the ordered choice that requires the parser to try the 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. +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 ----------------- @@ -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`` 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 -------------- diff --git a/doc/tut1.txt b/doc/tut1.txt index 7c2a35f94..2ca2a8ddd 100644 --- a/doc/tut1.txt +++ b/doc/tut1.txt @@ -515,6 +515,13 @@ contain indentation at certain places for better readability: As a rule of thumb, indentation within expressions is allowed after operators, 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 ========== diff --git a/todo.txt b/todo.txt index 46f557dfb..768d39747 100644 --- a/todo.txt +++ b/todo.txt @@ -7,8 +7,6 @@ version 0.9.2 - acyclic vs prunable; introduce GC hints - CGEN: ``restrict`` pragma + backend support; computed goto support - 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 - further expr/stmt unification: - rewrite nkCaseExpr handling @@ -59,6 +57,7 @@ version 0.9.X - improve the compiler as a service - better support for macros that rewrite procs - macros need access to types and symbols (partially implemented) +- effect propagation for callbacks - perhaps: change comment handling in the AST - enforce 'simpleExpr' more often --> doesn't work; tkProc is part of primary! |