summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/parser.nim26
-rw-r--r--tests/parser/tletcolon.nim33
-rw-r--r--web/news/e031_version_0_16_2.rst13
3 files changed, 62 insertions, 10 deletions
diff --git a/compiler/parser.nim b/compiler/parser.nim
index 84402ea3b..46953de1e 100644
--- a/compiler/parser.nim
+++ b/compiler/parser.nim
@@ -696,7 +696,7 @@ proc primarySuffix(p: var TParser, r: PNode, baseIndent: int): PNode =
       result = namedParams(p, result, nkCall, tkParRi)
       if result.len > 1 and result.sons[1].kind == nkExprColonExpr:
         result.kind = nkObjConstr
-      else:
+      elif p.tok.tokType == tkDo:
         parseDoBlocks(p, result)
     of tkDo:
       # progress guaranteed
@@ -972,10 +972,8 @@ proc optPragmas(p: var TParser): PNode =
   else:
     result = ast.emptyNode
 
-proc parseDoBlock(p: var TParser): PNode =
+proc parseDoBlock(p: var TParser; info: TLineInfo): PNode =
   #| doBlock = 'do' paramListArrow pragmas? colcom stmt
-  let info = parLineInfo(p)
-  getTok(p)
   let params = parseParamList(p, retColon=false)
   let pragmas = optPragmas(p)
   colcom(p, result)
@@ -985,11 +983,10 @@ proc parseDoBlock(p: var TParser): PNode =
 
 proc parseDoBlocks(p: var TParser, call: PNode) =
   #| doBlocks = doBlock ^* IND{=}
-  if p.tok.tokType == tkDo:
-    #withInd(p):
-    #  addSon(call, parseDoBlock(p))
-    while sameOrNoInd(p) and p.tok.tokType == tkDo:
-      addSon(call, parseDoBlock(p))
+  while sameOrNoInd(p) and p.tok.tokType == tkDo:
+    let info = parLineInfo(p)
+    getTok(p)
+    addSon(call, parseDoBlock(p, info))
 
 proc parseProcExpr(p: var TParser, isExpr: bool): PNode =
   #| procExpr = 'proc' paramListColon pragmas? ('=' COMMENT? stmt)?
@@ -1889,9 +1886,18 @@ proc parseVarTuple(p: var TParser): PNode =
   addSon(result, parseExpr(p))
 
 proc parseVariable(p: var TParser): PNode =
-  #| variable = (varTuple / identColonEquals) indAndComment
+  #| colonBody = colcom stmt doBlocks?
+  #| variable = (varTuple / identColonEquals) colonBody? indAndComment
   if p.tok.tokType == tkParLe: result = parseVarTuple(p)
   else: result = parseIdentColonEquals(p, {withPragma})
+  if p.tok.tokType == tkColon and p.tok.indent < 0:
+    let last = result.len-1
+    let ex = result.sons[last]
+    if ex.kind != nkEmpty:
+      let call = makeCall(ex)
+      call.add parseDoBlock(p, parLineInfo(p))
+      parseDoBlocks(p, call)
+      result.sons[last] = call
   indAndComment(p, result)
 
 proc parseBind(p: var TParser, k: TNodeKind): PNode =
diff --git a/tests/parser/tletcolon.nim b/tests/parser/tletcolon.nim
new file mode 100644
index 000000000..ec7c24106
--- /dev/null
+++ b/tests/parser/tletcolon.nim
@@ -0,0 +1,33 @@
+discard """
+  output: '''boo
+3
+44 3
+more body code
+yes
+yes'''
+"""
+
+template x(body): untyped =
+  body
+  44
+
+template y(val, body): untyped =
+  body
+  val
+
+proc mana =
+  let foo = x:
+    echo "boo"
+  var foo2 = y 3:
+    echo "3"
+  echo foo, " ", foo2
+
+mana()
+let other = x:
+  echo "more body code"
+  if true:
+    echo "yes"
+  else:
+    echo "no"
+let outer = y(5):
+  echo "yes"
diff --git a/web/news/e031_version_0_16_2.rst b/web/news/e031_version_0_16_2.rst
index 809910052..4c4cac129 100644
--- a/web/news/e031_version_0_16_2.rst
+++ b/web/news/e031_version_0_16_2.rst
@@ -96,6 +96,19 @@ remove the need for the ``newException`` template.
 - A new pragma ``.used`` can be used for symbols to prevent
 the "declared but not used" warning. More details can be
 found `here <http://nim-lang.org/docs/manual.html#pragmas-used-pragma>`_.
+- The popular "colon block of statements" syntax is now also supported for
+  ``let`` and ``var`` statements:
+
+.. code-block:: nim
+  template ve(value, effect): untyped =
+    effect
+    val
+
+  let x = ve(4):
+    echo "welcome to Nim!"
+
+This is particularly useful for DSLs that help in tree construction.
+
 
 
 Bugfixes