`do' keyword in the grammar for lambda blocks

This commit is contained in:
Zahary Karadjov
2012-02-10 14:50:06 +02:00
parent 74498d616e
commit 560a3bad28
14 changed files with 83 additions and 36 deletions

View File

@@ -93,6 +93,7 @@ type
nkElifExpr,
nkElseExpr,
nkLambda, # lambda expression
nkDo, # lambda block appering as trailing proc param
nkAccQuoted, # `a` as a node
nkTableConstr, # a table constructor {expr: expr}
@@ -644,6 +645,8 @@ proc copyTree*(src: PNode): PNode
const nkCallKinds* = {nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand,
nkCallStrLit}
const nkLambdaKinds* = {nkLambda, nkDo}
proc isCallExpr*(n: PNode): bool =
result = n.kind in nkCallKinds

View File

@@ -7,6 +7,8 @@
# distribution, for details about the copyright.
#
# included from cgen.nim
proc lenField: PRope {.inline.} =
result = toRope(if gCmd != cmdCompileToCpp: "Sup.len" else: "len")
@@ -1723,7 +1725,7 @@ proc expr(p: BProc, e: PNode, d: var TLoc) =
of nkChckRange: genRangeChck(p, e, d, "chckRange")
of nkStringToCString: convStrToCStr(p, e, d)
of nkCStringToString: convCStrToStr(p, e, d)
of nkLambda:
of nkLambdaKinds:
var sym = e.sons[namePos].sym
genProc(p.module, sym)
if sym.loc.r == nil or sym.loc.t == nil:

View File

@@ -1246,7 +1246,7 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
of nkPragmaBlock:
result = evalAux(c, n.sons[1], flags)
of nkIdentDefs, nkCast, nkYieldStmt, nkAsmStmt, nkForStmt, nkPragmaExpr,
nkLambda, nkContinueStmt, nkIdent:
nkLambdaKinds, nkContinueStmt, nkIdent:
result = raiseCannotEval(c, n.info)
of nkRefTy:
result = evalAux(c, n.sons[0], flags)

View File

@@ -8,11 +8,12 @@
#
# This include file implements lambda lifting for the transformator.
# included from transf.nim
const
declarativeDefs = {nkProcDef, nkMethodDef, nkIteratorDef,
nkConverterDef}
procDefs = {nkLambda} + declarativeDefs
procDefs = nkLambdaKinds + declarativeDefs
proc indirectAccess(a, b: PSym, info: TLineInfo): PNode =
# returns a[].b as a node
@@ -169,7 +170,7 @@ proc createEnvStmt(c: PTransf, varList: TCapture, env: PSym): PTransNode =
IdNodeTablePut(c.transCon.mapping, v, fieldAccess)
proc transformProcFin(c: PTransf, n: PNode, s: PSym): PTransNode =
if n.kind == nkLambda:
if n.kind in nkLambdaKinds:
# for lambdas we transformed 'n.sons[bodyPos]', but not 'ast.n[bodyPos]'!
s.ast.sons[bodyPos] = n.sons[bodyPos]
else:

View File

@@ -33,8 +33,9 @@ type
tkSymbol, # keywords:
tkAddr, tkAnd, tkAs, tkAsm, tkAtomic,
tkBind, tkBlock, tkBreak, tkCase, tkCast,
tkConst, tkContinue, tkConverter, tkDiscard, tkDistinct, tkDiv, tkElif,
tkElse, tkEnd, tkEnum, tkExcept, tkExport, tkFinally, tkFor, tkFrom,
tkConst, tkContinue, tkConverter, tkDiscard, tkDistinct, tkDiv, tkDo,
tkElif, tkElse, tkEnd, tkEnum, tkExcept, tkExport,
tkFinally, tkFor, tkFrom,
tkGeneric, tkIf, tkImport, tkIn, tkInclude, tkIs, tkIsnot, tkIterator,
tkLambda, tkLet,
tkMacro, tkMethod, tkMod, tkNil, tkNot, tkNotin, tkObject, tkOf, tkOr,
@@ -48,10 +49,12 @@ type
tkBracketDotLe, tkBracketDotRi, # [. and .]
tkCurlyDotLe, tkCurlyDotRi, # {. and .}
tkParDotLe, tkParDotRi, # (. and .)
tkComma, tkSemiColon, tkColon, tkColonColon, tkEquals, tkDot, tkDotDot,
tkComma, tkSemiColon,
tkColon, tkColonColon, tkEquals, tkLeArrow, tkRiArrow, tkDot, tkDotDot,
tkOpr, tkComment, tkAccent, tkInd, tkSad,
tkDed, # pseudo token types used by the source renderers:
tkSpaces, tkInfixOpr, tkPrefixOpr, tkPostfixOpr
tkSpaces, tkInfixOpr, tkPrefixOpr, tkPostfixOpr,
TTokTypes* = set[TTokType]
const
@@ -61,8 +64,8 @@ const
"tkSymbol",
"addr", "and", "as", "asm", "atomic",
"bind", "block", "break", "case", "cast",
"const", "continue", "converter", "discard", "distinct", "div", "elif",
"else", "end", "enum", "except", "export",
"const", "continue", "converter", "discard", "distinct", "div", "do",
"elif", "else", "end", "enum", "except", "export",
"finally", "for", "from", "generic", "if",
"import", "in", "include", "is", "isnot", "iterator",
"lambda", "let",
@@ -73,9 +76,10 @@ const
"tkIntLit", "tkInt8Lit", "tkInt16Lit", "tkInt32Lit", "tkInt64Lit",
"tkFloatLit", "tkFloat32Lit", "tkFloat64Lit", "tkStrLit", "tkRStrLit",
"tkTripleStrLit", "tkGStrLit", "tkGTripleStrLit", "tkCharLit", "(",
")", "[", "]", "{", "}", "[.", ".]", "{.", ".}", "(.", ".)", ",", ";",
":", "::",
"=", ".", "..", "tkOpr", "tkComment", "`", "[new indentation]",
")", "[", "]", "{", "}", "[.", ".]", "{.", ".}", "(.", ".)",
",", ";",
":", "::", "=", "<-", "->", ".", "..",
"tkOpr", "tkComment", "`", "[new indentation]",
"[same indentation]", "[dedentation]", "tkSpaces", "tkInfixOpr",
"tkPrefixOpr", "tkPostfixOpr"]

View File

@@ -146,7 +146,8 @@ proc newIdentNodeP(ident: PIdent, p: TParser): PNode =
proc parseExpr(p: var TParser): PNode
proc parseStmt(p: var TParser): PNode
proc parseTypeDesc(p: var TParser): PNode
proc parseParamList(p: var TParser): PNode
proc parseDoBlocks(p: var TParser, call: PNode)
proc parseParamList(p: var TParser, resTypeTok = tkColon): PNode
proc IsLeftAssociative(tok: TToken): bool {.inline.} =
result = tok.tokType != tkOpr or tok.ident.s[0] != '^'
@@ -466,6 +467,7 @@ proc primary(p: var TParser): PNode =
result = newNodeP(nkCall, p)
addSon(result, a)
exprColonEqExprListAux(p, nkExprEqExpr, tkParRi, tkEquals, result)
parseDoBlocks(p, result)
of tkDot:
result = newDotExpr(p, result)
result = parseGStrLit(p, result)
@@ -599,7 +601,7 @@ proc parseTuple(p: var TParser): PNode =
optPar(p)
eat(p, tkBracketRi)
proc parseParamList(p: var TParser): PNode =
proc parseParamList(p: var TParser, resTypeTok = tkColon): PNode =
var a: PNode
result = newNodeP(nkFormalParams, p)
addSon(result, ast.emptyNode) # return type
@@ -621,11 +623,33 @@ proc parseParamList(p: var TParser): PNode =
optInd(p, a)
optPar(p)
eat(p, tkParRi)
if p.tok.tokType == tkColon:
if p.tok.tokType == resTypeTok:
getTok(p)
optInd(p, result)
result.sons[0] = parseTypeDesc(p)
proc optPragmas(p: var TParser): PNode =
if p.tok.tokType == tkCurlyDotLe: result = parsePragma(p)
else: result = ast.emptyNode
proc parseDoBlock(p: var TParser): PNode =
var info = parLineInfo(p)
getTok(p)
var params = parseParamList(p, tkRiArrow)
var pragmas = optPragmas(p)
eat(p, tkColon)
result = newNodeI(nkDo, info)
addSon(result, ast.emptyNode) # no name part
addSon(result, ast.emptyNode) # no generic parameters
addSon(result, params)
addSon(result, pragmas)
skipComment(p, result)
addSon(result, parseStmt(p))
proc parseDoBlocks(p: var TParser, call: PNode) =
while p.tok.tokType == tkDo:
addSon(call, parseDoBlock(p))
proc parseProcExpr(p: var TParser, isExpr: bool): PNode =
# either a proc type or a anonymous proc
var
@@ -634,8 +658,7 @@ proc parseProcExpr(p: var TParser, isExpr: bool): PNode =
info = parLineInfo(p)
getTok(p)
params = parseParamList(p)
if p.tok.tokType == tkCurlyDotLe: pragmas = parsePragma(p)
else: pragmas = ast.emptyNode
pragmas = optPragmas(p)
if (p.tok.tokType == tkEquals) and isExpr:
result = newNodeI(nkLambda, info)
addSon(result, ast.emptyNode) # no name part
@@ -709,9 +732,12 @@ proc parseExprStmt(p: var TParser): PNode =
if p.tok.tokType != tkComma: break
getTok(p)
optInd(p, a)
if p.tok.tokType == tkDo:
parseDoBlocks(p, result)
return
if sonsLen(result) <= 1: result = a
else: a = result
if p.tok.tokType == tkColon:
if p.tok.tokType == tkColon:
# macro statement
result = newNodeP(nkMacroStmt, p)
result.info = a.info
@@ -746,7 +772,7 @@ proc parseExprStmt(p: var TParser): PNode =
addSon(b, parseStmt(p))
addSon(result, b)
if b.kind == nkElse: break
proc parseImportOrIncludeStmt(p: var TParser, kind: TNodeKind): PNode =
var a: PNode
result = newNodeP(kind, p)

View File

@@ -348,7 +348,7 @@ proc lsub(n: PNode): int =
of nkBind: result = lsons(n) + len("bind_")
of nkBindStmt: result = lcomma(n) + len("bind_")
of nkCheckedFieldExpr: result = lsub(n.sons[0])
of nkLambda: result = lsons(n) + len("lambda__=_")
of nkLambda, nkDo: result = lsons(n) + len("lambda__=_") # XXX: render nkDo
of nkConstDef, nkIdentDefs:
result = lcomma(n, 0, - 3)
var L = sonsLen(n)
@@ -785,7 +785,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
gsub(g, n.sons[0])
of nkCheckedFieldExpr, nkHiddenAddr, nkHiddenDeref:
gsub(g, n.sons[0])
of nkLambda:
of nkLambda, nkDo: # XXX: nkDo is rendered as regular lambda
assert(n.sons[genericParamsPos].kind == nkEmpty)
putWithSpace(g, tkLambda, "lambda")
gsub(g, n.sons[paramsPos])

View File

@@ -1279,7 +1279,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
of paSingle: result = semExpr(c, n.sons[0], flags)
of nkCurly: result = semSetConstr(c, n)
of nkBracket: result = semArrayConstr(c, n)
of nkLambda: result = semLambda(c, n)
of nkLambdaKinds: result = semLambda(c, n)
of nkDerefExpr: result = semDeref(c, n)
of nkAddr:
result = n

View File

@@ -244,9 +244,9 @@ proc semGenericStmt(c: PContext, n: PNode,
for j in countup(0, L-3):
addPrelimDecl(c, newSymS(skUnknown, getIdentNode(a.sons[j]), c))
of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef,
nkIteratorDef, nkLambda:
nkIteratorDef, nkLambdaKinds:
checkSonsLen(n, bodyPos + 1)
if n.kind != nkLambda:
if n.kind notin nkLambdaKinds:
addPrelimDecl(c, newSymS(skUnknown, getIdentNode(n.sons[0]), c))
openScope(c.tab)
n.sons[genericParamsPos] = semGenericStmt(c, n.sons[genericParamsPos],

View File

@@ -360,7 +360,7 @@ proc analyse(c: PProcCtx, n: PNode): TThreadOwner =
if n.sons[0].kind != nkEmpty: result = analyse(c, n.sons[0])
else: result = toVoid
of nkAsmStmt, nkPragma, nkIteratorDef, nkProcDef, nkMethodDef,
nkConverterDef, nkMacroDef, nkTemplateDef, nkLambda:
nkConverterDef, nkMacroDef, nkTemplateDef, nkLambdaKinds:
result = toVoid
of nkExprColonExpr:
result = analyse(c, n.sons[1])

View File

@@ -24,15 +24,17 @@ type
wAddr, wAnd, wAs, wAsm, wAtomic,
wBind, wBlock, wBreak, wCase, wCast, wConst,
wContinue, wConverter, wDiscard, wDistinct, wDiv, wElif, wElse, wEnd, wEnum,
wExcept, wExport, wFinally, wFor, wFrom, wGeneric, wIf, wImport, wIn,
wContinue, wConverter, wDiscard, wDistinct, wDiv, wDo,
wElif, wElse, wEnd, wEnum, wExcept, wExport,
wFinally, wFor, wFrom, wGeneric, wIf, wImport, wIn,
wInclude, wIs, wIsnot, wIterator, wLambda, wLet,
wMacro, wMethod, wMod, wNil,
wNot, wNotin, wObject, wOf, wOr, wOut, wProc, wPtr, wRaise, wRef, wReturn,
wShl, wShr, wTemplate, wTry, wTuple, wType, wVar, wWhen, wWhile, wWith,
wWithout, wXor, wYield,
wColon, wColonColon, wEquals, wDot, wDotDot, wStar, wMinus,
wColon, wColonColon, wEquals, wLeArraw, wRiArrow, wDot, wDotDot,
wStar, wMinus,
wMagic, wThread, wFinal, wProfiler, wObjChecks,
wImportCpp, wImportObjC,
wImportCompilerProc,
@@ -66,8 +68,9 @@ const
"addr", "and", "as", "asm", "atomic",
"bind", "block", "break", "case", "cast",
"const", "continue", "converter", "discard", "distinct", "div", "elif",
"else", "end", "enum", "except", "export",
"const", "continue", "converter",
"discard", "distinct", "div", "do",
"elif", "else", "end", "enum", "except", "export",
"finally", "for", "from", "generic", "if",
"import", "in", "include", "is", "isnot", "iterator",
"lambda", "let",
@@ -76,7 +79,8 @@ const
"try", "tuple", "type", "var", "when", "while", "with", "without", "xor",
"yield",
":", "::", "=", ".", "..", "*", "-",
":", "::", "=", "<-", "->", ".", "..",
"*", "-",
"magic", "thread", "final", "profiler", "objchecks",
"importcpp", "importobjc",

View File

@@ -1,9 +1,10 @@
addr and as asm atomic
bind block break
case cast const continue converter
discard distinct div
discard distinct div do
elif else end enum except export
finally for from generic
finally for from
generic
if import in include is isnot iterator
lambda let
macro method mod

View File

@@ -25,7 +25,7 @@ type
nnkPrefix, nnkPostfix, nnkPar, nnkCurly, nnkCurlyExpr,
nnkBracket, nnkBracketExpr, nnkPragmaExpr, nnkRange,
nnkDotExpr, nnkCheckedFieldExpr, nnkDerefExpr, nnkIfExpr,
nnkElifExpr, nnkElseExpr, nnkLambda, nnkAccQuoted,
nnkElifExpr, nnkElseExpr, nnkLambda, nnkDo, nnkAccQuoted,
nnkTableConstr, nnkBind, nnkSymChoice, nnkHiddenStdConv,
nnkHiddenSubConv, nnkHiddenCallConv, nnkConv, nnkCast,
nnkAddr, nnkHiddenAddr, nnkHiddenDeref, nnkObjDownConv,

View File

@@ -12,6 +12,10 @@ proc foldr(n: openarray[int], fn: proc (x, y: int): int {.closure}): int =
for i in 0..n.len-1:
result = fn(result, n[i])
proc each(n: openarray[int], fn: proc(x: int) {.closure.}) =
for i in 0..n.len-1:
fn(n[i])
var
myData: array[0..4, int] = [0, 1, 2, 3, 4]
@@ -24,8 +28,10 @@ proc testA() =
inc(p))
testA()
for x in items(myData):
myData.each do (x: int):
write(stout, x)
#OUT 2 4 6 8 10