This commit is contained in:
Araq
2015-01-12 01:43:25 +01:00
parent c87f1eb581
commit b9079b8713
8 changed files with 46 additions and 9 deletions

View File

@@ -1977,7 +1977,9 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
of skParam:
if sym.loc.r == nil or sym.loc.t == nil:
#echo "FAILED FOR PRCO ", p.prc.name.s
internalError(n.info, "expr: param not init " & sym.name.s & "_" & $sym.id)
#debug p.prc.typ.n
#echo renderTree(p.prc.ast, {renderIds})
internalError(n.info, "expr: param not init " & sym.name.s & "_" & $sym.id)
putLocIntoDest(p, d, sym.loc)
else: internalError(n.info, "expr(" & $sym.kind & "); unknown symbol")
of nkNilLit:

View File

@@ -29,7 +29,7 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) =
of nkSym:
var s = templ.sym
if s.owner.id == c.owner.id:
if s.kind == skParam:
if s.kind == skParam and sfGenSym notin s.flags:
let x = actual.sons[s.position]
if x.kind == nkArgList:
for y in items(x): result.add(y)

View File

@@ -35,6 +35,7 @@ type
inTryStmt*: int # whether we are in a try statement; works also
# in standalone ``except`` and ``finally``
next*: PProcCon # used for stacking procedure contexts
wasForwarded*: bool # whether the current proc has a separate header
TInstantiationPair* = object
genericSym*: PSym

View File

@@ -109,9 +109,16 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
# if a proc accesses a global variable, it is not side effect free:
if sfGlobal in s.flags:
incl(c.p.owner.flags, sfSideEffect)
elif s.kind == skParam and s.typ.kind == tyStatic and s.typ.n != nil:
# XXX see the hack in sigmatch.nim ...
return s.typ.n
elif s.kind == skParam:
if s.typ.kind == tyStatic and s.typ.n != nil:
# XXX see the hack in sigmatch.nim ...
return s.typ.n
elif sfGenSym in s.flags and c.p.wasForwarded:
# gensym'ed parameters that nevertheless have been forward declared
# need a special fixup:
let realParam = c.p.owner.typ.n[s.position+1]
internalAssert realParam.kind == nkSym and realParam.sym.kind == skParam
return newSymNode(c.p.owner.typ.n[s.position+1].sym, n.info)
result = newSymNode(s, n.info)
# We cannot check for access to outer vars for example because it's still
# not sure the symbol really ends up being used:

View File

@@ -982,7 +982,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
# process parameters:
if n.sons[paramsPos].kind != nkEmpty:
semParamList(c, n.sons[paramsPos], gp, s)
if sonsLen(gp) > 0:
if sonsLen(gp) > 0:
if n.sons[genericParamsPos].kind == nkEmpty:
# we have a list of implicit type parameters:
n.sons[genericParamsPos] = gp
@@ -1049,6 +1049,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
if n.sons[genericParamsPos].kind == nkEmpty or usePseudoGenerics:
if not usePseudoGenerics: paramsTypeCheck(c, s.typ)
pushProcCon(c, s)
c.p.wasForwarded = proto != nil
maybeAddResult(c, s, n)
if sfImportc notin s.flags:
# no semantic checking for importc:

View File

@@ -127,7 +127,7 @@ proc getIdentNode(c: var TemplCtx, n: PNode): PNode =
proc isTemplParam(c: TemplCtx, n: PNode): bool {.inline.} =
result = n.kind == nkSym and n.sym.kind == skParam and
n.sym.owner == c.owner
n.sym.owner == c.owner and sfGenSym notin n.sym.flags
proc semTemplBody(c: var TemplCtx, n: PNode): PNode
@@ -246,8 +246,8 @@ proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode =
n.sons[i] = semTemplBody(c, n.sons[i])
closeScope(c)
proc semTemplSomeDecl(c: var TemplCtx, n: PNode, symKind: TSymKind) =
for i in countup(0, sonsLen(n) - 1):
proc semTemplSomeDecl(c: var TemplCtx, n: PNode, symKind: TSymKind; start=0) =
for i in countup(start, sonsLen(n) - 1):
var a = n.sons[i]
if a.kind == nkCommentStmt: continue
if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): illFormedAst(a)
@@ -348,6 +348,10 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
a.sons[L-1] = semTemplBodyScope(c, a.sons[L-1])
of nkVarSection: semTemplSomeDecl(c, n, skVar)
of nkLetSection: semTemplSomeDecl(c, n, skLet)
of nkFormalParams:
checkMinSonsLen(n, 1)
n.sons[0] = semTemplBody(c, n.sons[0])
semTemplSomeDecl(c, n, skParam, 1)
of nkConstSection:
for i in countup(0, sonsLen(n) - 1):
var a = n.sons[i]
@@ -485,6 +489,11 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
# process parameters:
if n.sons[paramsPos].kind != nkEmpty:
semParamList(c, n.sons[paramsPos], gp, s)
# a template's parameters are not gensym'ed even if that was originally the
# case as we determine whether it's a template parameter in the template
# body by the absense of the skGenSym flag:
for i in 1 .. s.typ.n.len-1:
s.typ.n.sons[i].sym.flags.excl sfGenSym
if sonsLen(gp) > 0:
if n.sons[genericParamsPos].kind == nkEmpty:
# we have a list of implicit type parameters:

View File

@@ -0,0 +1,14 @@
# bug #1915
import macros
# Test that parameters are properly gensym'ed finally:
template genNodeKind(kind, name: expr): stmt =
proc name*(children: varargs[PNimrodNode]): PNimrodNode {.compiletime.}=
result = newNimNode(kind)
for c in children:
result.add(c)
genNodeKind(nnkNone, None)

View File

@@ -3,6 +3,9 @@ version 0.10
- The bitwise 'not' operator will be renamed to 'bnot' to
prevent 'not 4 == 5' from compiling. -> requires 'mixin' annotation for procs!
- parameter lists without type end up in 'experimental'
- iterators always require a return type
- revert tuple behaviour
- c2nim depends on the compiler
- make nimble part of the distribution