refactoring: fewer global variables

This commit is contained in:
Andreas Rumpf 2018-05-27 19:19:12 +02:00
commit a325692fb2
6 changed files with 36 additions and 43 deletions

View file

@ -10,4 +10,15 @@
## Include file that imports all plugins that are active. ## Include file that imports all plugins that are active.
import import
locals / locals, itersgen compiler / [pluginsupport, idents, ast], locals, itersgen
const
plugins: array[2, Plugin] = [
("stdlib", "system", "iterToProc", iterToProcImpl),
("stdlib", "system", "locals", semLocals)
]
proc getPlugin*(ic: IdentCache; fn: PSym): Transformation =
for p in plugins:
if pluginMatches(ic, p, fn): return p.t
return nil

View file

@ -9,11 +9,11 @@
## Plugin to transform an inline iterator into a data structure. ## Plugin to transform an inline iterator into a data structure.
import ".." / [pluginsupport, ast, astalgo, import ".." / [ast, astalgo,
magicsys, lookups, semdata, magicsys, lookups, semdata,
lambdalifting, rodread, msgs] lambdalifting, rodread, msgs]
proc iterToProcImpl(c: PContext, n: PNode): PNode = proc iterToProcImpl*(c: PContext, n: PNode): PNode =
result = newNodeI(nkStmtList, n.info) result = newNodeI(nkStmtList, n.info)
let iter = n[1] let iter = n[1]
if iter.kind != nkSym or iter.sym.kind != skIterator: if iter.kind != nkSym or iter.sym.kind != skIterator:
@ -46,5 +46,3 @@ proc iterToProcImpl(c: PContext, n: PNode): PNode =
prc.ast.add iter.sym.ast.sons[resultPos] prc.ast.add iter.sym.ast.sons[resultPos]
addInterfaceDecl(c, prc) addInterfaceDecl(c, prc)
registerPlugin("stdlib", "system", "iterToProc", iterToProcImpl)

View file

@ -9,10 +9,10 @@
## The builtin 'system.locals' implemented as a plugin. ## The builtin 'system.locals' implemented as a plugin.
import "../../" / [pluginsupport, ast, astalgo, import ".." / [pluginsupport, ast, astalgo,
magicsys, lookups, semdata, lowerings] magicsys, lookups, semdata, lowerings]
proc semLocals(c: PContext, n: PNode): PNode = proc semLocals*(c: PContext, n: PNode): PNode =
var counter = 0 var counter = 0
var tupleType = newTypeS(tyTuple, c) var tupleType = newTypeS(tyTuple, c)
result = newNodeIT(nkPar, n.info, tupleType) result = newNodeIT(nkPar, n.info, tupleType)
@ -39,5 +39,3 @@ proc semLocals(c: PContext, n: PNode): PNode =
var a = newSymNode(it, result.info) var a = newSymNode(it, result.info)
if it.typ.skipTypes({tyGenericInst}).kind == tyVar: a = newDeref(a) if it.typ.skipTypes({tyGenericInst}).kind == tyVar: a = newDeref(a)
result.add(a) result.add(a)
registerPlugin("stdlib", "system", "locals", semLocals)

View file

@ -8,40 +8,26 @@
# #
## Plugin support for the Nim compiler. Right now plugins ## Plugin support for the Nim compiler. Right now plugins
## need to be built with the compiler only: plugins using ## need to be built with the compiler only: plugins using
## DLLs or the FFI will not work. ## DLLs or the FFI will not work.
import ast, semdata, idents import ast, semdata, idents
type type
Transformation* = proc (c: PContext; n: PNode): PNode {.nimcall.} Transformation* = proc (c: PContext; n: PNode): PNode {.nimcall.}
Plugin = ref object Plugin* = tuple
fn, module, package: PIdent package, module, fn: string
t: Transformation t: Transformation
next: Plugin
proc pluginMatches(p: Plugin; s: PSym): bool = proc pluginMatches*(ic: IdentCache; p: Plugin; s: PSym): bool =
if s.name.id != p.fn.id: if s.name.id != ic.getIdent(p.fn).id:
return false return false
let module = s.skipGenericOwner let module = s.skipGenericOwner
if module == nil or module.kind != skModule or if module == nil or module.kind != skModule or
module.name.id != p.module.id: module.name.id != ic.getIdent(p.module).id:
return false return false
let package = module.owner let package = module.owner
if package == nil or package.kind != skPackage or if package == nil or package.kind != skPackage or
package.name.id != p.package.id: package.name.id != ic.getIdent(p.package).id:
return false return false
return true return true
var head: Plugin
proc getPlugin*(fn: PSym): Transformation =
var it = head
while it != nil:
if pluginMatches(it, fn): return it.t
it = it.next
proc registerPlugin*(package, module, fn: string; t: Transformation) =
let oldHead = head
head = Plugin(fn: getIdent(fn), module: getIdent(module),
package: getIdent(package), t: t, next: oldHead)

View file

@ -11,11 +11,11 @@ type
onStack: bool onStack: bool
kids: seq[DepN] kids: seq[DepN]
hAQ, hIS, hB, hCmd: int hAQ, hIS, hB, hCmd: int
when not defined(release): when defined(debugReorder):
expls: seq[string] expls: seq[string]
DepG = seq[DepN] DepG = seq[DepN]
when not defined(release): when defined(debugReorder):
var idNames = newTable[int, string]() var idNames = newTable[int, string]()
proc newDepN(id: int, pnode: PNode): DepN = proc newDepN(id: int, pnode: PNode): DepN =
@ -30,7 +30,7 @@ proc newDepN(id: int, pnode: PNode): DepN =
result.hIS = -1 result.hIS = -1
result.hB = -1 result.hB = -1
result.hCmd = -1 result.hCmd = -1
when not defined(release): when defined(debugReorder):
result.expls = @[] result.expls = @[]
proc accQuoted(n: PNode): PIdent = proc accQuoted(n: PNode): PIdent =
@ -49,16 +49,16 @@ proc addDecl(n: PNode; declares: var IntSet) =
of nkPragmaExpr: addDecl(n[0], declares) of nkPragmaExpr: addDecl(n[0], declares)
of nkIdent: of nkIdent:
declares.incl n.ident.id declares.incl n.ident.id
when not defined(release): when defined(debugReorder):
idNames[n.ident.id] = n.ident.s idNames[n.ident.id] = n.ident.s
of nkSym: of nkSym:
declares.incl n.sym.name.id declares.incl n.sym.name.id
when not defined(release): when defined(debugReorder):
idNames[n.sym.name.id] = n.sym.name.s idNames[n.sym.name.id] = n.sym.name.s
of nkAccQuoted: of nkAccQuoted:
let a = accQuoted(n) let a = accQuoted(n)
declares.incl a.id declares.incl a.id
when not defined(release): when defined(debugReorder):
idNames[a.id] = a.s idNames[a.id] = a.s
of nkEnumFieldDef: of nkEnumFieldDef:
addDecl(n[0], declares) addDecl(n[0], declares)
@ -216,7 +216,7 @@ proc mergeSections(conf: ConfigRef; comps: seq[seq[DepN]], res: PNode) =
# consecutive type and const sections # consecutive type and const sections
var wmsg = "Circular dependency detected. reorder pragma may not be able to" & var wmsg = "Circular dependency detected. reorder pragma may not be able to" &
" reorder some nodes properely" " reorder some nodes properely"
when not defined(release): when defined(debugReorder):
wmsg &= ":\n" wmsg &= ":\n"
for i in 0..<cs.len-1: for i in 0..<cs.len-1:
for j in i..<cs.len: for j in i..<cs.len:
@ -355,13 +355,13 @@ proc buildGraph(n: PNode, deps: seq[(IntSet, IntSet)]): DepG =
if j < i and nj.hasCommand and niHasCmd: if j < i and nj.hasCommand and niHasCmd:
# Preserve order for commands and calls # Preserve order for commands and calls
ni.kids.add nj ni.kids.add nj
when not defined(release): when defined(debugReorder):
ni.expls.add "both have commands and one comes after the other" ni.expls.add "both have commands and one comes after the other"
elif j < i and nj.hasImportStmt: elif j < i and nj.hasImportStmt:
# Every node that comes after an import statement must # Every node that comes after an import statement must
# depend on that import # depend on that import
ni.kids.add nj ni.kids.add nj
when not defined(release): when defined(debugReorder):
ni.expls.add "parent is, or contains, an import statement and child comes after it" ni.expls.add "parent is, or contains, an import statement and child comes after it"
elif j < i and niHasBody and nj.hasAccQuotedDef: elif j < i and niHasBody and nj.hasAccQuotedDef:
# Every function, macro, template... with a body depends # Every function, macro, template... with a body depends
@ -369,13 +369,13 @@ proc buildGraph(n: PNode, deps: seq[(IntSet, IntSet)]): DepG =
# That's because it is hard to detect the use of functions # That's because it is hard to detect the use of functions
# like "[]=", "[]", "or" ... in their bodies. # like "[]=", "[]", "or" ... in their bodies.
ni.kids.add nj ni.kids.add nj
when not defined(release): when defined(debugReorder):
ni.expls.add "one declares a quoted identifier and the other has a body and comes after it" ni.expls.add "one declares a quoted identifier and the other has a body and comes after it"
elif j < i and niHasBody and not nj.hasBody and elif j < i and niHasBody and not nj.hasBody and
intersects(deps[i][0], declares): intersects(deps[i][0], declares):
# Keep function declaration before function definition # Keep function declaration before function definition
ni.kids.add nj ni.kids.add nj
when not defined(release): when defined(debugReorder):
for dep in deps[i][0]: for dep in deps[i][0]:
if dep in declares: if dep in declares:
ni.expls.add "one declares \"" & idNames[dep] & "\" and the other defines it" ni.expls.add "one declares \"" & idNames[dep] & "\" and the other defines it"
@ -383,7 +383,7 @@ proc buildGraph(n: PNode, deps: seq[(IntSet, IntSet)]): DepG =
for d in declares: for d in declares:
if uses.contains(d): if uses.contains(d):
ni.kids.add nj ni.kids.add nj
when not defined(release): when defined(debugReorder):
ni.expls.add "one declares \"" & idNames[d] & "\" and the other uses it" ni.expls.add "one declares \"" & idNames[d] & "\" and the other uses it"
proc strongConnect(v: var DepN, idx: var int, s: var seq[DepN], proc strongConnect(v: var DepN, idx: var int, s: var seq[DepN],

View file

@ -279,7 +279,7 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
of mRoof: of mRoof:
localError(c.config, n.info, "builtin roof operator is not supported anymore") localError(c.config, n.info, "builtin roof operator is not supported anymore")
of mPlugin: of mPlugin:
let plugin = getPlugin(n[0].sym) let plugin = getPlugin(c.cache, n[0].sym)
if plugin.isNil: if plugin.isNil:
localError(c.config, n.info, "cannot find plugin " & n[0].sym.name.s) localError(c.config, n.info, "cannot find plugin " & n[0].sym.name.s)
result = n result = n