parent
33b8a00aa8
commit
560eef5bbe
3 changed files with 35 additions and 12 deletions
|
|
@ -85,7 +85,8 @@ proc getPragmaVal*(procAst: PNode; name: TSpecialWord): PNode =
|
||||||
it[0].ident.id == ord(name):
|
it[0].ident.id == ord(name):
|
||||||
return it[1]
|
return it[1]
|
||||||
|
|
||||||
proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords)
|
proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords;
|
||||||
|
isStatement: bool = false)
|
||||||
|
|
||||||
proc recordPragma(c: PContext; n: PNode; key, val: string; val2 = "") =
|
proc recordPragma(c: PContext; n: PNode; key, val: string; val2 = "") =
|
||||||
var recorded = newNodeI(nkCommentStmt, n.info)
|
var recorded = newNodeI(nkCommentStmt, n.info)
|
||||||
|
|
@ -747,7 +748,8 @@ proc semCustomPragma(c: PContext, n: PNode): PNode =
|
||||||
result.kind = n.kind
|
result.kind = n.kind
|
||||||
|
|
||||||
proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||||
validPragmas: TSpecialWords, comesFromPush: bool) : bool =
|
validPragmas: TSpecialWords,
|
||||||
|
comesFromPush, isStatement: bool) : bool =
|
||||||
var it = n.sons[i]
|
var it = n.sons[i]
|
||||||
var key = if it.kind in nkPragmaCallKinds and it.len > 1: it.sons[0] else: it
|
var key = if it.kind in nkPragmaCallKinds and it.len > 1: it.sons[0] else: it
|
||||||
if key.kind == nkBracketExpr:
|
if key.kind == nkBracketExpr:
|
||||||
|
|
@ -767,7 +769,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||||
if c.instCounter > 100:
|
if c.instCounter > 100:
|
||||||
globalError(c.config, it.info, "recursive dependency: " & userPragma.name.s)
|
globalError(c.config, it.info, "recursive dependency: " & userPragma.name.s)
|
||||||
|
|
||||||
pragma(c, sym, userPragma.ast, validPragmas)
|
pragma(c, sym, userPragma.ast, validPragmas, isStatement)
|
||||||
n.sons[i..i] = userPragma.ast.sons # expand user pragma with its content
|
n.sons[i..i] = userPragma.ast.sons # expand user pragma with its content
|
||||||
i.inc(userPragma.ast.len - 1) # inc by -1 is ok, user pragmas was empty
|
i.inc(userPragma.ast.len - 1) # inc by -1 is ok, user pragmas was empty
|
||||||
dec c.instCounter
|
dec c.instCounter
|
||||||
|
|
@ -969,7 +971,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||||
recordPragma(c, it, "warning", s)
|
recordPragma(c, it, "warning", s)
|
||||||
message(c.config, it.info, warnUser, s)
|
message(c.config, it.info, warnUser, s)
|
||||||
of wError:
|
of wError:
|
||||||
if sym != nil and (sym.isRoutine or sym.kind == skType) and wUsed in validPragmas:
|
if sym != nil and (sym.isRoutine or sym.kind == skType) and not isStatement:
|
||||||
# This is subtle but correct: the error *statement* is only
|
# This is subtle but correct: the error *statement* is only
|
||||||
# allowed when 'wUsed' is not in validPragmas. Here this is the easiest way to
|
# allowed when 'wUsed' is not in validPragmas. Here this is the easiest way to
|
||||||
# distinguish properly between
|
# distinguish properly between
|
||||||
|
|
@ -1168,7 +1170,7 @@ proc implicitPragmas*(c: PContext, sym: PSym, n: PNode,
|
||||||
pushInfoContext(c.config, n.info)
|
pushInfoContext(c.config, n.info)
|
||||||
var i = 0
|
var i = 0
|
||||||
while i < o.len:
|
while i < o.len:
|
||||||
if singlePragma(c, sym, o, i, validPragmas, true):
|
if singlePragma(c, sym, o, i, validPragmas, true, false):
|
||||||
internalError(c.config, n.info, "implicitPragmas")
|
internalError(c.config, n.info, "implicitPragmas")
|
||||||
inc i
|
inc i
|
||||||
popInfoContext(c.config)
|
popInfoContext(c.config)
|
||||||
|
|
@ -1193,14 +1195,16 @@ proc hasPragma*(n: PNode, pragma: TSpecialWord): bool =
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|
||||||
proc pragmaRec(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
|
proc pragmaRec(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords;
|
||||||
|
isStatement: bool) =
|
||||||
if n == nil: return
|
if n == nil: return
|
||||||
var i = 0
|
var i = 0
|
||||||
while i < n.len:
|
while i < n.len:
|
||||||
if singlePragma(c, sym, n, i, validPragmas, false): break
|
if singlePragma(c, sym, n, i, validPragmas, false, isStatement): break
|
||||||
inc i
|
inc i
|
||||||
|
|
||||||
proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
|
proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords;
|
||||||
|
isStatement: bool) =
|
||||||
if n == nil: return
|
if n == nil: return
|
||||||
pragmaRec(c, sym, n, validPragmas)
|
pragmaRec(c, sym, n, validPragmas, isStatement)
|
||||||
implicitPragmas(c, sym, n, validPragmas)
|
implicitPragmas(c, sym, n, validPragmas)
|
||||||
|
|
|
||||||
|
|
@ -2748,7 +2748,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
of nkUsingStmt: result = semUsing(c, n)
|
of nkUsingStmt: result = semUsing(c, n)
|
||||||
of nkAsmStmt: result = semAsm(c, n)
|
of nkAsmStmt: result = semAsm(c, n)
|
||||||
of nkYieldStmt: result = semYield(c, n)
|
of nkYieldStmt: result = semYield(c, n)
|
||||||
of nkPragma: pragma(c, c.p.owner, n, stmtPragmas)
|
of nkPragma: pragma(c, c.p.owner, n, stmtPragmas, true)
|
||||||
of nkIteratorDef: result = semIterator(c, n)
|
of nkIteratorDef: result = semIterator(c, n)
|
||||||
of nkProcDef: result = semProc(c, n)
|
of nkProcDef: result = semProc(c, n)
|
||||||
of nkFuncDef: result = semFunc(c, n)
|
of nkFuncDef: result = semFunc(c, n)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
discard """
|
discard """
|
||||||
errormsg: "cannot attach a custom pragma to 'a'"
|
cmd: "nim check --hint[processing]:off $file"
|
||||||
line: 9
|
errormsg: "3 is not two"
|
||||||
|
nimout: '''t8741.nim(13, 9) Error: cannot attach a custom pragma to 'a'
|
||||||
|
t8741.nim(29, 15) template/generic instantiation of `onlyTwo` from here
|
||||||
|
t8741.nim(25, 12) Error: 3 is not two
|
||||||
|
'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for a {.gensym, inject.} in @[1,2,3]:
|
for a {.gensym, inject.} in @[1,2,3]:
|
||||||
|
|
@ -8,3 +12,18 @@ for a {.gensym, inject.} in @[1,2,3]:
|
||||||
|
|
||||||
for a {.foobar.} in @[1,2,3]:
|
for a {.foobar.} in @[1,2,3]:
|
||||||
discard
|
discard
|
||||||
|
|
||||||
|
type Foo[N: static[int]] = distinct int
|
||||||
|
|
||||||
|
proc isTwo(n: int): bool =
|
||||||
|
n == 2
|
||||||
|
|
||||||
|
proc onlyTwo[N: static[int]](a: Foo[N]): int =
|
||||||
|
when isTwo(N):
|
||||||
|
int(a)
|
||||||
|
else:
|
||||||
|
{.error: $(N) & " is not two".}
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
let foo: Foo[3] = Foo[3](5)
|
||||||
|
echo onlyTwo(foo)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue