diff options
author | Araq <rumpf_a@web.de> | 2012-09-20 23:44:52 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2012-09-20 23:44:52 +0200 |
commit | 043921c7a7d7ba50872c3a48f063a5d7b9d6b6b0 (patch) | |
tree | 261349a336b2fd948ab5e6b97038d51a08e96e57 /compiler | |
parent | e741583f7b01fecefef9c61ed70dcb6f234b9a07 (diff) | |
download | Nim-043921c7a7d7ba50872c3a48f063a5d7b9d6b6b0.tar.gz |
fixes #194
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/sem.nim | 4 | ||||
-rwxr-xr-x | compiler/semdata.nim | 5 | ||||
-rwxr-xr-x | compiler/semexprs.nim | 2 | ||||
-rwxr-xr-x | compiler/semgnrc.nim | 9 | ||||
-rwxr-xr-x | compiler/seminst.nim | 18 |
5 files changed, 34 insertions, 4 deletions
diff --git a/compiler/sem.nim b/compiler/sem.nim index 16dd2d107..e1f2fb21c 100755 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -234,10 +234,12 @@ proc myProcess(context: PPassContext, n: PNode): PNode = result = SemStmtAndGenerateGenerics(c, n) else: let oldContextLen = msgs.getInfoContextLen() + let oldInGenericInst = c.InGenericInst try: result = SemStmtAndGenerateGenerics(c, n) except ERecoverableError: RecoverContext(c) + c.InGenericInst = oldInGenericInst result = ast.emptyNode msgs.setInfoContextLen(oldContextLen) if gCmd == cmdIdeTools: findSuggest(c, n) @@ -261,7 +263,7 @@ proc myClose(context: PPassContext, n: PNode): PNode = popOwner() popProcCon(c) -proc semPass(): TPass = +proc semPass(): TPass = initPass(result) result.open = myOpen result.openCached = myOpenCached diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 02768c90b..fe6f43f44 100755 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -63,12 +63,15 @@ type tab*: TSymTab # each module has its own symbol table AmbiguousSymbols*: TIntSet # ids of all ambiguous symbols (cannot # store this info in the syms themselves!) - InGenericContext*: int # > 0 if we are in a generic + InGenericContext*: int # > 0 if we are in a generic type InUnrolledContext*: int # > 0 if we are unrolling a loop InCompilesContext*: int # > 0 if we are in a ``compiles`` magic + InGenericInst*: int # > 0 if we are instantiating a generic converters*: TSymSeq # sequence of converters patterns*: TSymSeq # sequence of pattern matchers optionStack*: TLinkedList + symMapping*: TIdTable # every gensym'ed symbol needs to be mapped + # to some new symbol in a generic instantiation libs*: TLinkedList # all libs used by this module semConstExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # for the pragmas semExpr*: proc (c: PContext, n: PNode): PNode {.nimcall.} # for the pragmas diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index a08d50307..8a42a7090 100755 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1211,6 +1211,7 @@ proc semCompiles(c: PContext, n: PNode, flags: TExprFlags): PNode = let oldInGenericContext = c.InGenericContext let oldInUnrolledContext = c.InUnrolledContext + let oldInGenericInst = c.InGenericInst let oldProcCon = c.p c.generics = newGenericsCache() try: @@ -1222,6 +1223,7 @@ proc semCompiles(c: PContext, n: PNode, flags: TExprFlags): PNode = c.generics = oldGenerics c.InGenericContext = oldInGenericContext c.InUnrolledContext = oldInUnrolledContext + c.InGenericInst = oldInGenericInst c.p = oldProcCon msgs.setInfoContextLen(oldContextLen) setlen(gOwners, oldOwnerLen) diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 434dd7155..2751aa1e1 100755 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -91,7 +91,14 @@ proc semGenericStmt(c: PContext, n: PNode, var s = QualifiedLookUp(c, n, luf) if s != nil: result = semGenericStmtSymbol(c, n, s) # XXX for example: ``result.add`` -- ``add`` needs to be looked up here... - of nkEmpty, nkSym..nkNilLit: + of nkEmpty, nkSym..nkNilLit: + # see tests/compile/tgensymgeneric.nim: + # We need to open the gensym'ed symbol again so that the instantiation + # creates a fresh copy; but this is wrong the very first reason for gensym + # is that scope rules cannot be used! So simply removing 'sfGenSym' does + # not work. Copying the symbol does not work either because we're already + # the owner of the symbol! What we need to do is to copy the symbol + # in the generic instantiation process... nil of nkBind: result = semGenericStmt(c, n.sons[0], flags+{withinBind}, toBind) diff --git a/compiler/seminst.nim b/compiler/seminst.nim index ffda48fba..135f9bba9 100755 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -69,6 +69,18 @@ proc removeDefaultParamValues(n: PNode) = # not possible... XXX We don't solve this issue here. a.sons[L-1] = ast.emptyNode +proc freshGenSyms(n: PNode, owner: PSym, symMap: var TIdTable) = + # we need to create a fresh set of gensym'ed symbols: + if n.kind == nkSym and sfGenSym in n.sym.flags: + var x = PSym(IdTableGet(symMap, n.sym)) + if x == nil: + x = copySym(n.sym, false) + x.owner = owner + IdTablePut(symMap, n.sym, x) + n.sym = x + else: + for i in 0 .. <safeLen(n): freshGenSyms(n.sons[i], owner, symMap) + proc instantiateBody(c: PContext, n: PNode, result: PSym) = if n.sons[bodyPos].kind != nkEmpty: # add it here, so that recursive generic procs are possible: @@ -77,7 +89,11 @@ proc instantiateBody(c: PContext, n: PNode, result: PSym) = if result.kind in {skProc, skMethod, skConverter, skMacro}: addResult(c, result.typ.sons[0], n.info, result.kind) addResultNode(c, n) - var b = semStmtScope(c, n.sons[bodyPos]) + var b = n.sons[bodyPos] + var symMap: TIdTable + InitIdTable symMap + freshGenSyms(b, result, symMap) + b = semStmtScope(c, b) b = hloBody(c, b) n.sons[bodyPos] = transformBody(c.module, b, result) #echo "code instantiated ", result.name.s |