mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-07 04:14:19 +00:00
steps to get for loops as expressions
This commit is contained in:
@@ -514,7 +514,7 @@ proc parsePar(p: var TParser): PNode =
|
||||
optInd(p, result)
|
||||
if p.tok.tokType in {tkDiscard, tkInclude, tkIf, tkWhile, tkCase,
|
||||
tkTry, tkDefer, tkFinally, tkExcept, tkFor, tkBlock,
|
||||
tkConst, tkLet, tkWhen, tkVar,
|
||||
tkConst, tkLet, tkWhen, tkVar, tkFor,
|
||||
tkMixin}:
|
||||
# XXX 'bind' used to be an expression, so we exclude it here;
|
||||
# tests/reject/tbind2 fails otherwise.
|
||||
@@ -1039,7 +1039,7 @@ proc parseProcExpr(p: var TParser; isExpr: bool; kind: TNodeKind): PNode =
|
||||
|
||||
proc isExprStart(p: TParser): bool =
|
||||
case p.tok.tokType
|
||||
of tkSymbol, tkAccent, tkOpr, tkNot, tkNil, tkCast, tkIf,
|
||||
of tkSymbol, tkAccent, tkOpr, tkNot, tkNil, tkCast, tkIf, tkFor,
|
||||
tkProc, tkFunc, tkIterator, tkBind, tkAddr,
|
||||
tkParLe, tkBracketLe, tkCurlyLe, tkIntLit..tkCharLit, tkVar, tkRef, tkPtr,
|
||||
tkTuple, tkObject, tkType, tkWhen, tkCase, tkOut:
|
||||
@@ -1078,16 +1078,35 @@ proc parseTypeDescKAux(p: var TParser, kind: TNodeKind,
|
||||
result.addSon list
|
||||
parseSymbolList(p, list)
|
||||
|
||||
proc parseFor(p: var TParser): PNode =
|
||||
#| forStmt = 'for' (identWithPragma ^+ comma) 'in' expr colcom stmt
|
||||
#| forExpr = forStmt
|
||||
result = newNodeP(nkForStmt, p)
|
||||
getTokNoInd(p)
|
||||
var a = identWithPragma(p)
|
||||
addSon(result, a)
|
||||
while p.tok.tokType == tkComma:
|
||||
getTok(p)
|
||||
optInd(p, a)
|
||||
a = identWithPragma(p)
|
||||
addSon(result, a)
|
||||
eat(p, tkIn)
|
||||
addSon(result, parseExpr(p))
|
||||
colcom(p, result)
|
||||
addSon(result, parseStmt(p))
|
||||
|
||||
proc parseExpr(p: var TParser): PNode =
|
||||
#| expr = (blockExpr
|
||||
#| | ifExpr
|
||||
#| | whenExpr
|
||||
#| | caseExpr
|
||||
#| | forExpr
|
||||
#| | tryExpr)
|
||||
#| / simpleExpr
|
||||
case p.tok.tokType:
|
||||
of tkBlock: result = parseBlock(p)
|
||||
of tkIf: result = parseIfExpr(p, nkIfExpr)
|
||||
of tkFor: result = parseFor(p)
|
||||
of tkWhen: result = parseIfExpr(p, nkWhenExpr)
|
||||
of tkCase: result = parseCase(p)
|
||||
of tkTry: result = parseTry(p, isExpr=true)
|
||||
@@ -1498,22 +1517,6 @@ proc parseExceptBlock(p: var TParser, kind: TNodeKind): PNode =
|
||||
colcom(p, result)
|
||||
addSon(result, parseStmt(p))
|
||||
|
||||
proc parseFor(p: var TParser): PNode =
|
||||
#| forStmt = 'for' (identWithPragma ^+ comma) 'in' expr colcom stmt
|
||||
result = newNodeP(nkForStmt, p)
|
||||
getTokNoInd(p)
|
||||
var a = identWithPragma(p)
|
||||
addSon(result, a)
|
||||
while p.tok.tokType == tkComma:
|
||||
getTok(p)
|
||||
optInd(p, a)
|
||||
a = identWithPragma(p)
|
||||
addSon(result, a)
|
||||
eat(p, tkIn)
|
||||
addSon(result, parseExpr(p))
|
||||
colcom(p, result)
|
||||
addSon(result, parseStmt(p))
|
||||
|
||||
proc parseBlock(p: var TParser): PNode =
|
||||
#| blockStmt = 'block' symbol? colcom stmt
|
||||
#| blockExpr = 'block' symbol? colcom stmt
|
||||
|
||||
@@ -679,7 +679,7 @@ proc semForVars(c: PContext, n: PNode): PNode =
|
||||
addForVarDecl(c, v)
|
||||
inc(c.p.nestedLoopCounter)
|
||||
openScope(c)
|
||||
n.sons[length-1] = semStmt(c, n.sons[length-1])
|
||||
n.sons[length-1] = semExprBranch(c, n.sons[length-1])
|
||||
closeScope(c)
|
||||
dec(c.p.nestedLoopCounter)
|
||||
|
||||
@@ -732,8 +732,18 @@ proc semFor(c: PContext, n: PNode): PNode =
|
||||
else:
|
||||
result = semForVars(c, n)
|
||||
# propagate any enforced VoidContext:
|
||||
if n.sons[length-1].typ == enforceVoidContext:
|
||||
result.typ = enforceVoidContext
|
||||
let bodyType = n.sons[length-1].typ
|
||||
if bodyType == enforceVoidContext or isEmptyType(bodyType):
|
||||
result.typ = bodyType
|
||||
else:
|
||||
# if the body of a for loop is of type 'T', the
|
||||
# loop's type is 'iterator (): T'
|
||||
proc createForLoopExpr(c: PContext; t: PType; info: TLineInfo): PType {.nimcall.} =
|
||||
result = newType(tyGenericInvocation, c.module)
|
||||
addSonSkipIntLit(result, magicsys.getCompilerProc("ForLoopExpr").typ)
|
||||
addSonSkipIntLit(result, t)
|
||||
result = instGenericContainer(c, info, result, allowMetaTypes = false)
|
||||
result.typ = createForLoopExpr(c, bodyType, result.info)
|
||||
closeScope(c)
|
||||
|
||||
proc semRaise(c: PContext, n: PNode): PNode =
|
||||
|
||||
@@ -902,7 +902,7 @@ proc newIfStmt*(branches: varargs[tuple[cond, body: NimNode]]):
|
||||
##
|
||||
result = newNimNode(nnkIfStmt)
|
||||
for i in branches:
|
||||
result.add(newNimNode(nnkElifBranch).add(i.cond, i.body))
|
||||
result.add(newTree(nnkElifBranch, i.cond, i.body))
|
||||
|
||||
proc newEnum*(name: NimNode, fields: openArray[NimNode],
|
||||
public, pure: bool): NimNode {.compileTime.} =
|
||||
@@ -1227,7 +1227,7 @@ proc customPragmaNode(n: NimNode): NimNode =
|
||||
let recList = typDef[2][2]
|
||||
for identDefs in recList:
|
||||
for i in 0 .. identDefs.len - 3:
|
||||
if identDefs[i].kind == nnkPragmaExpr and
|
||||
if identDefs[i].kind == nnkPragmaExpr and
|
||||
identDefs[i][0].kind == nnkIdent and $identDefs[i][0] == $n[1]:
|
||||
return identDefs[i][1]
|
||||
|
||||
@@ -1237,7 +1237,7 @@ macro hasCustomPragma*(n: typed, cp: typed{nkSym}): untyped =
|
||||
##
|
||||
## .. code-block:: nim
|
||||
## template myAttr() {.pragma.}
|
||||
## type
|
||||
## type
|
||||
## MyObj = object
|
||||
## myField {.myAttr.}: int
|
||||
## var o: MyObj
|
||||
@@ -1255,7 +1255,7 @@ macro getCustomPragmaVal*(n: typed, cp: typed{nkSym}): untyped =
|
||||
##
|
||||
## .. code-block:: nim
|
||||
## template serializationKey(key: string) {.pragma.}
|
||||
## type
|
||||
## type
|
||||
## MyObj = object
|
||||
## myField {.serializationKey: "mf".}: int
|
||||
## var o: MyObj
|
||||
|
||||
@@ -4131,3 +4131,6 @@ when defined(cpp) and appType != "lib" and not defined(js) and
|
||||
stderr.write trace & "Error: unhandled exception: " & ex.msg &
|
||||
" [" & $ex.name & "]\n"
|
||||
quit 1
|
||||
|
||||
type
|
||||
ForLoopExpr*{.compilerProc.}[T] = object ## the type of a 'for' loop expression
|
||||
|
||||
Reference in New Issue
Block a user