From df0f0f28589c6aad9fc34a924194aa9932120e6e Mon Sep 17 00:00:00 2001 From: Andrii Riabushenko Date: Tue, 11 Dec 2018 23:35:46 +0000 Subject: [PATCH 1/3] custom pragmas in pragma blocks --- compiler/pragmas.nim | 4 ++-- compiler/semstmts.nim | 12 +++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 247f6ad54e..f67e74f111 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -1111,8 +1111,8 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, else: sym.flags.incl sfUsed of wLiftLocals: discard else: invalidPragma(c, it) - elif sym != nil and sym.kind in {skVar, skLet, skParam, skField, skProc, - skFunc, skConverter, skMethod, skType}: + elif sym == nil or (sym != nil and sym.kind in {skVar, skLet, skParam, + skField, skProc, skFunc, skConverter, skMethod, skType}): n.sons[i] = semCustomPragma(c, it) elif sym != nil: illegalCustomPragma(c, it, sym) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 04fe91cfba..aec03b492c 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1876,18 +1876,16 @@ proc setLine(n: PNode, info: TLineInfo) = n.info = info proc semPragmaBlock(c: PContext, n: PNode): PNode = + checkSonsLen(n, 2, c.config) let pragmaList = n.sons[0] pragma(c, nil, pragmaList, exprPragmas) - result = semExpr(c, n.sons[1]) - n.sons[1] = result + n[1] = semExpr(c, n[1]) + result = n + result.typ = n[1].typ for i in 0 ..< pragmaList.len: case whichPragma(pragmaList.sons[i]) of wLine: setLine(result, pragmaList.sons[i].info) - of wLocks, wGcSafe, wNosideeffect: - result = n - result.typ = n.sons[1].typ - of wNoRewrite: - incl(result.flags, nfNoRewrite) + of wNoRewrite: incl(result.flags, nfNoRewrite) else: discard proc semStaticStmt(c: PContext, n: PNode): PNode = From 9becb41e0408d6627dcc7acd735ec71147fc929e Mon Sep 17 00:00:00 2001 From: Andrii Riabushenko Date: Tue, 11 Dec 2018 23:37:48 +0000 Subject: [PATCH 2/3] Add changelog item --- changelog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/changelog.md b/changelog.md index 093ea7ae2e..f245ce54ac 100644 --- a/changelog.md +++ b/changelog.md @@ -94,6 +94,9 @@ proc enumToString*(enums: openArray[enum]): string = - There is a new pragma block `noSideEffect` that works like the `gcsafe` pragma block. - added os.getCurrentProcessId() +- User defined pragmas are now allowed in the pragma blocks +- Pragma blocks are now longer eliminated from the typed AST tree to preserve + pragmas for further analysis by macros ### Language changes From 1d16676dd6a31de03bfc87a5dfdee482b27b51b5 Mon Sep 17 00:00:00 2001 From: Andrii Riabushenko Date: Tue, 11 Dec 2018 23:53:59 +0000 Subject: [PATCH 3/3] add test --- tests/pragmas/tcustom_pragma.nim | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/pragmas/tcustom_pragma.nim b/tests/pragmas/tcustom_pragma.nim index ae0f396317..0bc4d2f18b 100644 --- a/tests/pragmas/tcustom_pragma.nim +++ b/tests/pragmas/tcustom_pragma.nim @@ -174,3 +174,25 @@ type var foo: Something foo.cardinal = north doAssert foo.b.hasCustomPragma(thingy) == true + + +proc myproc(s: string): int = + {.thingy.}: + s.len + +doAssert myproc("123") == 3 + +let xx = compiles: + proc myproc_bad(s: string): int = + {.not_exist.}: + s.len +doAssert: xx == false + + +macro checkSym(s: typed{nkSym}): untyped = + let body = s.getImpl.body + doAssert body[1].kind == nnkPragmaBlock + doAssert body[1][0].kind == nnkPragma + doAssert body[1][0][0] == bindSym"thingy" + +checkSym(myproc) \ No newline at end of file