diff options
Diffstat (limited to 'compiler/semgnrc.nim')
-rwxr-xr-x | compiler/semgnrc.nim | 119 |
1 files changed, 69 insertions, 50 deletions
diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 4b0c81433..dc0be54cb 100755 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -32,12 +32,12 @@ proc getIdentNode(n: PNode): PNode = result = n proc semGenericStmt(c: PContext, n: PNode, flags: TSemGenericFlags, - toBind: var TIntSet): PNode + ctx: var TIntSet): PNode proc semGenericStmtScope(c: PContext, n: PNode, flags: TSemGenericFlags, - toBind: var TIntSet): PNode = + ctx: var TIntSet): PNode = openScope(c.tab) - result = semGenericStmt(c, n, flags, toBind) + result = semGenericStmt(c, n, flags, ctx) closeScope(c.tab) template macroToExpand(s: expr): expr = @@ -73,20 +73,35 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym): PNode = result = n else: result = newSymNode(s, n.info) +proc semMixinStmt(c: PContext, n: PNode, toMixin: var TIntSet): PNode = + for i in 0 .. < n.len: + toMixin.incl(considerAcc(n.sons[i]).id) + result = newNodeI(nkNilLit, n.info) + +proc Lookup(c: PContext, n: PNode, flags: TSemGenericFlags, + ctx: var TIntSet): PNode = + result = n + let ident = considerAcc(n) + var s = SymtabGet(c.Tab, ident) + if s == nil: + if ident.id notin ctx and withinMixin notin flags: + localError(n.info, errUndeclaredIdentifier, ident.s) + else: + if withinMixin in flags: + result = symChoice(c, n, s, scClosed) + elif s.name.id in ctx: + result = symChoice(c, n, s, scForceOpen) + else: + result = semGenericStmtSymbol(c, n, s) + # else: leave as nkIdent + proc semGenericStmt(c: PContext, n: PNode, - flags: TSemGenericFlags, toBind: var TIntSet): PNode = + flags: TSemGenericFlags, ctx: var TIntSet): PNode = result = n if gCmd == cmdIdeTools: suggestStmt(c, n) case n.kind of nkIdent, nkAccQuoted: - var s = SymtabGet(c.Tab, n.ident) - if s == nil: - if withinMixin notin flags: - localError(n.info, errUndeclaredIdentifier, n.ident.s) - else: - if withinBind in flags or s.id in toBind: - result = symChoice(c, n, s, scClosed) - else: result = semGenericStmtSymbol(c, n, s) + result = Lookup(c, n, flags, ctx) of nkDotExpr: let luf = if withinMixin notin flags: {checkUndeclared} else: {} var s = QualifiedLookUp(c, n, luf) @@ -101,15 +116,19 @@ proc semGenericStmt(c: PContext, n: PNode, # 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) - of nkBindStmt: - result = semBindStmt(c, n, toBind) + of nkBind: + result = semGenericStmt(c, n.sons[0], flags+{withinBind}, ctx) + of nkMixinStmt: + result = semMixinStmt(c, n, ctx) of nkCall, nkHiddenCallConv, nkInfix, nkPrefix, nkCommand, nkCallStrLit: # check if it is an expression macro: checkMinSonsLen(n, 1) - let luf = if withinMixin notin flags: {checkUndeclared} else: {} - var s = qualifiedLookup(c, n.sons[0], luf) + let fn = n.sons[0] + var s = qualifiedLookup(c, fn, {}) + if s == nil and withinMixin notin flags and + fn.kind in {nkIdent, nkAccQuoted} and considerAcc(fn).id notin ctx: + localError(n.info, errUndeclaredIdentifier, fn.renderTree) + var first = 0 var isDefinedMagic = false if s != nil: @@ -152,54 +171,54 @@ proc semGenericStmt(c: PContext, n: PNode, # is not exported and yet the generic 'threadProcWrapper' works correctly. let flags = if isDefinedMagic: flags+{withinMixin} else: flags for i in countup(first, sonsLen(result) - 1): - result.sons[i] = semGenericStmt(c, result.sons[i], flags, toBind) + result.sons[i] = semGenericStmt(c, result.sons[i], flags, ctx) of nkIfStmt: for i in countup(0, sonsLen(n)-1): - n.sons[i] = semGenericStmtScope(c, n.sons[i], flags, toBind) + n.sons[i] = semGenericStmtScope(c, n.sons[i], flags, ctx) of nkWhenStmt: for i in countup(0, sonsLen(n)-1): - n.sons[i] = semGenericStmt(c, n.sons[i], flags+{withinMixin}, toBind) + n.sons[i] = semGenericStmt(c, n.sons[i], flags+{withinMixin}, ctx) of nkWhileStmt: openScope(c.tab) for i in countup(0, sonsLen(n)-1): - n.sons[i] = semGenericStmt(c, n.sons[i], flags, toBind) + n.sons[i] = semGenericStmt(c, n.sons[i], flags, ctx) closeScope(c.tab) of nkCaseStmt: openScope(c.tab) - n.sons[0] = semGenericStmt(c, n.sons[0], flags, toBind) + n.sons[0] = semGenericStmt(c, n.sons[0], flags, ctx) for i in countup(1, sonsLen(n)-1): var a = n.sons[i] checkMinSonsLen(a, 1) var L = sonsLen(a) for j in countup(0, L-2): - a.sons[j] = semGenericStmt(c, a.sons[j], flags, toBind) - a.sons[L - 1] = semGenericStmtScope(c, a.sons[L-1], flags, toBind) + a.sons[j] = semGenericStmt(c, a.sons[j], flags, ctx) + a.sons[L - 1] = semGenericStmtScope(c, a.sons[L-1], flags, ctx) closeScope(c.tab) of nkForStmt, nkParForStmt: var L = sonsLen(n) openScope(c.tab) - n.sons[L - 2] = semGenericStmt(c, n.sons[L-2], flags, toBind) + n.sons[L - 2] = semGenericStmt(c, n.sons[L-2], flags, ctx) for i in countup(0, L - 3): addPrelimDecl(c, newSymS(skUnknown, n.sons[i], c)) - n.sons[L - 1] = semGenericStmt(c, n.sons[L-1], flags, toBind) + n.sons[L - 1] = semGenericStmt(c, n.sons[L-1], flags, ctx) closeScope(c.tab) of nkBlockStmt, nkBlockExpr, nkBlockType: checkSonsLen(n, 2) openScope(c.tab) if n.sons[0].kind != nkEmpty: addPrelimDecl(c, newSymS(skUnknown, n.sons[0], c)) - n.sons[1] = semGenericStmt(c, n.sons[1], flags, toBind) + n.sons[1] = semGenericStmt(c, n.sons[1], flags, ctx) closeScope(c.tab) of nkTryStmt: checkMinSonsLen(n, 2) - n.sons[0] = semGenericStmtScope(c, n.sons[0], flags, toBind) + n.sons[0] = semGenericStmtScope(c, n.sons[0], flags, ctx) for i in countup(1, sonsLen(n)-1): var a = n.sons[i] checkMinSonsLen(a, 1) var L = sonsLen(a) for j in countup(0, L-2): - a.sons[j] = semGenericStmt(c, a.sons[j], flags+{withinTypeDesc}, toBind) - a.sons[L-1] = semGenericStmtScope(c, a.sons[L-1], flags, toBind) + a.sons[j] = semGenericStmt(c, a.sons[j], flags+{withinTypeDesc}, ctx) + a.sons[L-1] = semGenericStmtScope(c, a.sons[L-1], flags, ctx) of nkVarSection, nkLetSection: for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] @@ -208,8 +227,8 @@ proc semGenericStmt(c: PContext, n: PNode, checkMinSonsLen(a, 3) var L = sonsLen(a) a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, - toBind) - a.sons[L-1] = semGenericStmt(c, a.sons[L-1], flags, toBind) + ctx) + a.sons[L-1] = semGenericStmt(c, a.sons[L-1], flags, ctx) for j in countup(0, L-3): addPrelimDecl(c, newSymS(skUnknown, getIdentNode(a.sons[j]), c)) of nkGenericParams: @@ -219,7 +238,7 @@ proc semGenericStmt(c: PContext, n: PNode, checkMinSonsLen(a, 3) var L = sonsLen(a) a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, - toBind) + ctx) # do not perform symbol lookup for default expressions for j in countup(0, L-3): addPrelimDecl(c, newSymS(skUnknown, getIdentNode(a.sons[j]), c)) @@ -230,8 +249,8 @@ proc semGenericStmt(c: PContext, n: PNode, if (a.kind != nkConstDef): IllFormedAst(a) checkSonsLen(a, 3) addPrelimDecl(c, newSymS(skUnknown, getIdentNode(a.sons[0]), c)) - a.sons[1] = semGenericStmt(c, a.sons[1], flags+{withinTypeDesc}, toBind) - a.sons[2] = semGenericStmt(c, a.sons[2], flags, toBind) + a.sons[1] = semGenericStmt(c, a.sons[1], flags+{withinTypeDesc}, ctx) + a.sons[2] = semGenericStmt(c, a.sons[2], flags, ctx) of nkTypeSection: for i in countup(0, sonsLen(n) - 1): var a = n.sons[i] @@ -246,15 +265,15 @@ proc semGenericStmt(c: PContext, n: PNode, checkSonsLen(a, 3) if a.sons[1].kind != nkEmpty: openScope(c.tab) - a.sons[1] = semGenericStmt(c, a.sons[1], flags, toBind) - a.sons[2] = semGenericStmt(c, a.sons[2], flags+{withinTypeDesc}, toBind) + a.sons[1] = semGenericStmt(c, a.sons[1], flags, ctx) + a.sons[2] = semGenericStmt(c, a.sons[2], flags+{withinTypeDesc}, ctx) closeScope(c.tab) else: - a.sons[2] = semGenericStmt(c, a.sons[2], flags+{withinTypeDesc}, toBind) + a.sons[2] = semGenericStmt(c, a.sons[2], flags+{withinTypeDesc}, ctx) of nkEnumTy: if n.sonsLen > 0: if n.sons[0].kind != nkEmpty: - n.sons[0] = semGenericStmt(c, n.sons[0], flags+{withinTypeDesc}, toBind) + n.sons[0] = semGenericStmt(c, n.sons[0], flags+{withinTypeDesc}, ctx) for i in countup(1, sonsLen(n) - 1): var a: PNode case n.sons[i].kind @@ -267,15 +286,15 @@ proc semGenericStmt(c: PContext, n: PNode, of nkFormalParams: checkMinSonsLen(n, 1) if n.sons[0].kind != nkEmpty: - n.sons[0] = semGenericStmt(c, n.sons[0], flags+{withinTypeDesc}, toBind) + n.sons[0] = semGenericStmt(c, n.sons[0], flags+{withinTypeDesc}, ctx) for i in countup(1, sonsLen(n) - 1): var a = n.sons[i] if (a.kind != nkIdentDefs): IllFormedAst(a) checkMinSonsLen(a, 3) var L = sonsLen(a) a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, - toBind) - a.sons[L-1] = semGenericStmt(c, a.sons[L-1], flags, toBind) + ctx) + a.sons[L-1] = semGenericStmt(c, a.sons[L-1], flags, ctx) for j in countup(0, L-3): addPrelimDecl(c, newSymS(skUnknown, getIdentNode(a.sons[j]), c)) of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef, @@ -285,22 +304,22 @@ proc semGenericStmt(c: PContext, n: PNode, addPrelimDecl(c, newSymS(skUnknown, getIdentNode(n.sons[0]), c)) openScope(c.tab) n.sons[genericParamsPos] = semGenericStmt(c, n.sons[genericParamsPos], - flags, toBind) + flags, ctx) if n.sons[paramsPos].kind != nkEmpty: if n.sons[paramsPos].sons[0].kind != nkEmpty: addPrelimDecl(c, newSym(skUnknown, getIdent("result"), nil, n.info)) - n.sons[paramsPos] = semGenericStmt(c, n.sons[paramsPos], flags, toBind) - n.sons[pragmasPos] = semGenericStmt(c, n.sons[pragmasPos], flags, toBind) + n.sons[paramsPos] = semGenericStmt(c, n.sons[paramsPos], flags, ctx) + n.sons[pragmasPos] = semGenericStmt(c, n.sons[pragmasPos], flags, ctx) var body: PNode if n.sons[namePos].kind == nkSym: body = n.sons[namePos].sym.getBody else: body = n.sons[bodyPos] - n.sons[bodyPos] = semGenericStmtScope(c, body, flags, toBind) + n.sons[bodyPos] = semGenericStmtScope(c, body, flags, ctx) closeScope(c.tab) of nkPragma, nkPragmaExpr: nil of nkExprColonExpr: checkMinSonsLen(n, 2) - result.sons[1] = semGenericStmt(c, n.sons[1], flags, toBind) - else: + result.sons[1] = semGenericStmt(c, n.sons[1], flags, ctx) + else: for i in countup(0, sonsLen(n) - 1): - result.sons[i] = semGenericStmt(c, n.sons[i], flags, toBind) + result.sons[i] = semGenericStmt(c, n.sons[i], flags, ctx) |