From 9280473eb149eba2bd7fda1c3b2925a8ce7831e8 Mon Sep 17 00:00:00 2001 From: Araq Date: Thu, 25 Dec 2014 17:22:41 +0100 Subject: [PATCH] fixes #1120 --- compiler/ast.nim | 6 ++++++ compiler/parser.nim | 8 ++++++-- compiler/sem.nim | 1 - compiler/semexprs.nim | 25 +++++-------------------- compiler/semgnrc.nim | 2 -- compiler/semstmts.nim | 5 ++++- compiler/sigmatch.nim | 4 ++-- doc/manual/procs.txt | 7 ++----- tests/macros/tvtable.nim | 4 ++-- todo.txt | 4 ++-- web/news.txt | 7 +++++-- 11 files changed, 34 insertions(+), 39 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index 64b59a283d..565bb43535 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1560,3 +1560,9 @@ proc isEmptyType*(t: PType): bool {.inline.} = ## 'void' and 'stmt' types are often equivalent to 'nil' these days: result = t == nil or t.kind in {tyEmpty, tyStmt} +proc makeStmtList*(n: PNode): PNode = + if n.kind == nkStmtList: + result = n + else: + result = newNodeI(nkStmtList, n.info) + result.add n diff --git a/compiler/parser.nim b/compiler/parser.nim index ff620b5fbc..fab3c453b3 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -894,7 +894,8 @@ proc parseParamList(p: var TParser, retColon = true): PNode = var a: PNode result = newNodeP(nkFormalParams, p) addSon(result, ast.emptyNode) # return type - if p.tok.tokType == tkParLe and p.tok.indent < 0: + let hasParLe = p.tok.tokType == tkParLe and p.tok.indent < 0 + if hasParLe: getTok(p) optInd(p, result) while true: @@ -918,6 +919,9 @@ proc parseParamList(p: var TParser, retColon = true): PNode = getTok(p) optInd(p, result) result.sons[0] = parseTypeDesc(p) + elif not retColon and not hasParle: + # Mark as "not there" in order to mark for deprecation in the semantic pass: + result = ast.emptyNode proc optPragmas(p: var TParser): PNode = if p.tok.tokType == tkCurlyDotLe and (p.tok.indent < 0 or realInd(p)): @@ -1130,7 +1134,7 @@ proc parseMacroColon(p: var TParser, x: PNode): PNode = skipComment(p, result) if p.tok.tokType notin {tkOf, tkElif, tkElse, tkExcept}: let body = parseStmt(p) - addSon(result, newProcNode(nkDo, body.info, body)) + addSon(result, makeStmtList(body)) while sameInd(p): var b: PNode case p.tok.tokType diff --git a/compiler/sem.nim b/compiler/sem.nim index 5160af20a2..91adcac5ee 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -41,7 +41,6 @@ proc addParams(c: PContext, n: PNode, kind: TSymKind) proc maybeAddResult(c: PContext, s: PSym, n: PNode) proc instGenericContainer(c: PContext, n: PNode, header: PType): PType proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode -proc fixImmediateParams(n: PNode): PNode proc activate(c: PContext, n: PNode) proc semQuoteAst(c: PContext, n: PNode): PNode proc finishMethod(c: PContext, s: PSym) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index fc217262e5..25113aa5a9 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1505,11 +1505,11 @@ proc semQuoteAst(c: PContext, n: PNode): PNode = doBlk.sons[namePos] = newAnonSym(skTemplate, n.info).newSymNode if ids.len > 0: - doBlk[paramsPos].sons.setLen(2) - doBlk[paramsPos].sons[0] = getSysSym("stmt").newSymNode # return type + doBlk.sons[paramsPos] = newNodeI(nkFormalParams, n.info) + doBlk[paramsPos].add getSysSym("stmt").newSymNode # return type ids.add getSysSym("expr").newSymNode # params type ids.add emptyNode # no default value - doBlk[paramsPos].sons[1] = newNode(nkIdentDefs, n.info, ids) + doBlk[paramsPos].add newNode(nkIdentDefs, n.info, ids) var tmpl = semTemplateDef(c, doBlk) quotes[0] = tmpl[namePos] @@ -1892,19 +1892,6 @@ proc semBlock(c: PContext, n: PNode): PNode = closeScope(c) dec(c.p.nestedBlockCounter) -proc doBlockIsStmtList(n: PNode): bool = - result = n.kind == nkDo and - n[paramsPos].sonsLen == 1 and - n[paramsPos][0].kind == nkEmpty - -proc fixImmediateParams(n: PNode): PNode = - # XXX: Temporary work-around until we carry out - # the planned overload resolution reforms - for i in 1 .. 0 and n.sons[genericParamsPos].kind == nkEmpty: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index ba493bdfa8..1ec48bd0e4 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1153,8 +1153,8 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType, of isEqual: inc(m.exactMatches) of isNone: discard - if f.kind == tyStmt and argOrig.kind == nkDo: - return argOrig[bodyPos] + if f.kind == tyStmt: + return arg elif f.kind == tyTypeDesc: return arg elif f.kind == tyStatic: diff --git a/doc/manual/procs.txt b/doc/manual/procs.txt index 156e96f1b3..2ebbe494da 100644 --- a/doc/manual/procs.txt +++ b/doc/manual/procs.txt @@ -200,6 +200,8 @@ executable code. Do notation ----------- +**Note:** The future of the ``do`` notation is uncertain. + As a special more convenient notation, proc expressions involved in procedure calls can use the ``do`` keyword: @@ -224,11 +226,6 @@ More than one ``do`` block can appear in a single call: do: # code to undo it -For compatibility with ``stmt`` templates and macros, the ``do`` keyword can be -omitted if the supplied proc doesn't have any parameters and return value. -The compatibility works in the other direction too as the ``do`` syntax can be -used with macros and templates expecting ``stmt`` blocks. - Nonoverloadable builtins ------------------------ diff --git a/tests/macros/tvtable.nim b/tests/macros/tvtable.nim index 51894618c7..3e3b9c0e6e 100644 --- a/tests/macros/tvtable.nim +++ b/tests/macros/tvtable.nim @@ -11,8 +11,8 @@ OBJ 2 bar type # these are the signatures of the virtual procs for each type - fooProc[T] = proc (o: var T): int - barProc[T] = proc (o: var T) + fooProc[T] = proc (o: var T): int {.nimcall.} + barProc[T] = proc (o: var T) {.nimcall.} # an untyped table to store the proc pointers # it's also possible to use a strongly typed tuple here diff --git a/todo.txt b/todo.txt index 6b1ec569f8..1272df575e 100644 --- a/todo.txt +++ b/todo.txt @@ -3,8 +3,6 @@ version 0.10 - The bitwise 'not' operator will be renamed to 'bnot' to prevent 'not 4 == 5' from compiling. -> requires 'mixin' annotation for procs! -- The 'do' notation might be trimmed so that its only purpose is to pass - multiple multi line constructs to a macro. - c2nim depends on the compiler - make nimble part of the distribution @@ -62,6 +60,8 @@ version 0.9.x - we need a magic thisModule symbol - ensure (ref T)(a, b) works as a type conversion and type constructor - optimize 'genericReset'; 'newException' leads to code bloat +- The 'do' notation might be trimmed so that its only purpose is to pass + multiple multi line constructs to a macro. version 0.9.X diff --git a/web/news.txt b/web/news.txt index c55620431d..f95de759b3 100644 --- a/web/news.txt +++ b/web/news.txt @@ -22,8 +22,8 @@ News compiler changed from ``nimrod`` to ``nim`` too. - ``system.fileHandle`` has been renamed to ``system.getFileHandle`` to prevent name conflicts with the new type ``FileHandle``. - - Comments are now not part of the AST, as such you cannot use them in place - of ``discard``. + - Comments are now not part of the AST anymore, as such you cannot use them + in place of ``discard``. - Large parts of the stdlib got rid of the T/P type prefixes. Instead most types now simply start with an uppercased letter. The so called "partial case sensitivity" rule is now active allowing for code @@ -51,6 +51,9 @@ News work better. - Field names in tuples are now ignored for type comparisons. This allows for greater interoperability between different modules. + - Statement lists are not converted to an implicit ``do`` block anymore. This + means the confusing ``nnkDo`` nodes when working with macros are gone for + good. Language Additions