Merge pull request #9937 from cooldome/pragmablock_custom_pragma

Language feature: implement custom pragmas in pragma blocks
This commit is contained in:
Andreas Rumpf 2018-12-12 10:15:25 +01:00 • committed by GitHub
commit d9ae9201c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 9 deletions

View file

@ -113,6 +113,9 @@ proc enumToString*(enums: openArray[enum]): string =
- There is a new pragma block `noSideEffect` that works like - There is a new pragma block `noSideEffect` that works like
the `gcsafe` pragma block. the `gcsafe` pragma block.
- added os.getCurrentProcessId() - 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 ### Language changes

View file

@ -1111,8 +1111,8 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
else: sym.flags.incl sfUsed else: sym.flags.incl sfUsed
of wLiftLocals: discard of wLiftLocals: discard
else: invalidPragma(c, it) else: invalidPragma(c, it)
elif sym != nil and sym.kind in {skVar, skLet, skParam, skField, skProc, elif sym == nil or (sym != nil and sym.kind in {skVar, skLet, skParam,
skFunc, skConverter, skMethod, skType}: skField, skProc, skFunc, skConverter, skMethod, skType}):
n.sons[i] = semCustomPragma(c, it) n.sons[i] = semCustomPragma(c, it)
elif sym != nil: elif sym != nil:
illegalCustomPragma(c, it, sym) illegalCustomPragma(c, it, sym)

View file

@ -1876,18 +1876,16 @@ proc setLine(n: PNode, info: TLineInfo) =
n.info = info n.info = info
proc semPragmaBlock(c: PContext, n: PNode): PNode = proc semPragmaBlock(c: PContext, n: PNode): PNode =
checkSonsLen(n, 2, c.config)
let pragmaList = n.sons[0] let pragmaList = n.sons[0]
pragma(c, nil, pragmaList, exprPragmas) pragma(c, nil, pragmaList, exprPragmas)
result = semExpr(c, n.sons[1]) n[1] = semExpr(c, n[1])
n.sons[1] = result result = n
result.typ = n[1].typ
for i in 0 ..< pragmaList.len: for i in 0 ..< pragmaList.len:
case whichPragma(pragmaList.sons[i]) case whichPragma(pragmaList.sons[i])
of wLine: setLine(result, pragmaList.sons[i].info) of wLine: setLine(result, pragmaList.sons[i].info)
of wLocks, wGcSafe, wNosideeffect: of wNoRewrite: incl(result.flags, nfNoRewrite)
result = n
result.typ = n.sons[1].typ
of wNoRewrite:
incl(result.flags, nfNoRewrite)
else: discard else: discard
proc semStaticStmt(c: PContext, n: PNode): PNode = proc semStaticStmt(c: PContext, n: PNode): PNode =

View file

@ -174,3 +174,25 @@ type
var foo: Something var foo: Something
foo.cardinal = north foo.cardinal = north
doAssert foo.b.hasCustomPragma(thingy) == true 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)