language addition: colon-block for expressions in let/var context

This commit is contained in:
Andreas Rumpf
2017-04-02 15:05:04 +02:00
parent d7eb146d28
commit a543b89bf8
3 changed files with 62 additions and 10 deletions

View File

@@ -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 =

View File

@@ -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"

View File

@@ -94,6 +94,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