diff options
Diffstat (limited to 'compiler/passes.nim')
-rw-r--r-- | compiler/passes.nim | 98 |
1 files changed, 49 insertions, 49 deletions
diff --git a/compiler/passes.nim b/compiler/passes.nim index 96088bd88..129d8ad47 100644 --- a/compiler/passes.nim +++ b/compiler/passes.nim @@ -10,15 +10,15 @@ # This module implements the passes functionality. A pass must implement the # `TPass` interface. -import - strutils, lists, options, ast, astalgo, llstream, msgs, platform, os, - condsyms, idents, renderer, types, extccomp, math, magicsys, nversion, +import + strutils, lists, options, ast, astalgo, llstream, msgs, platform, os, + condsyms, idents, renderer, types, extccomp, math, magicsys, nversion, nimsets, syntaxes, times, rodread, idgen -type +type TPassContext* = object of RootObj # the pass's context fromCache*: bool # true if created by "openCached" - + PPassContext* = ref TPassContext TPassOpen* = proc (module: PSym): PPassContext {.nimcall.} @@ -33,8 +33,8 @@ type TPassData* = tuple[input: PNode, closeOutput: PNode] TPasses* = openArray[TPass] -# a pass is a tuple of procedure vars ``TPass.close`` may produce additional -# nodes. These are passed to the other close procedures. +# a pass is a tuple of procedure vars ``TPass.close`` may produce additional +# nodes. These are passed to the other close procedures. # This mechanism used to be used for the instantiation of generics. proc makePass*(open: TPassOpen = nil, @@ -53,46 +53,46 @@ proc makePass*(open: TPassOpen = nil, proc processModule*(module: PSym, stream: PLLStream, rd: PRodReader) # the semantic checker needs these: -var +var gImportModule*: proc (m: PSym, fileIdx: int32): PSym {.nimcall.} gIncludeFile*: proc (m: PSym, fileIdx: int32): PNode {.nimcall.} # implementation -proc skipCodegen*(n: PNode): bool {.inline.} = - # can be used by codegen passes to determine whether they should do +proc skipCodegen*(n: PNode): bool {.inline.} = + # can be used by codegen passes to determine whether they should do # something with `n`. Currently, this ignores `n` and uses the global # error count instead. result = msgs.gErrorCounter > 0 -proc astNeeded*(s: PSym): bool = +proc astNeeded*(s: PSym): bool = # The ``rodwrite`` module uses this to determine if the body of a proc # needs to be stored. The passes manager frees s.sons[codePos] when # appropriate to free the procedure body's memory. This is important # to keep memory usage down. if (s.kind in {skMethod, skProc}) and ({sfCompilerProc, sfCompileTime} * s.flags == {}) and - (s.typ.callConv != ccInline) and - (s.ast.sons[genericParamsPos].kind == nkEmpty): + (s.typ.callConv != ccInline) and + (s.ast.sons[genericParamsPos].kind == nkEmpty): result = false # XXX this doesn't really make sense with excessive CTFE else: result = true - -const + +const maxPasses = 10 -type +type TPassContextArray = array[0..maxPasses - 1, PPassContext] -var +var gPasses: array[0..maxPasses - 1, TPass] gPassesLen*: int proc clearPasses* = gPassesLen = 0 -proc registerPass*(p: TPass) = +proc registerPass*(p: TPass) = gPasses[gPassesLen] = p inc(gPassesLen) @@ -109,48 +109,48 @@ proc carryPasses*(nodes: PNode, module: PSym, passes: TPasses) = passdata = carryPass(pass, module, passdata) proc openPasses(a: var TPassContextArray, module: PSym) = - for i in countup(0, gPassesLen - 1): - if not isNil(gPasses[i].open): + for i in countup(0, gPassesLen - 1): + if not isNil(gPasses[i].open): a[i] = gPasses[i].open(module) else: a[i] = nil - + proc openPassesCached(a: var TPassContextArray, module: PSym, rd: PRodReader) = - for i in countup(0, gPassesLen - 1): - if not isNil(gPasses[i].openCached): + for i in countup(0, gPassesLen - 1): + if not isNil(gPasses[i].openCached): a[i] = gPasses[i].openCached(module, rd) - if a[i] != nil: + if a[i] != nil: a[i].fromCache = true else: a[i] = nil - -proc closePasses(a: var TPassContextArray) = + +proc closePasses(a: var TPassContextArray) = var m: PNode = nil - for i in countup(0, gPassesLen - 1): + for i in countup(0, gPassesLen - 1): if not isNil(gPasses[i].close): m = gPasses[i].close(a[i], m) a[i] = nil # free the memory here - -proc processTopLevelStmt(n: PNode, a: var TPassContextArray): bool = + +proc processTopLevelStmt(n: PNode, a: var TPassContextArray): bool = # this implements the code transformation pipeline var m = n - for i in countup(0, gPassesLen - 1): - if not isNil(gPasses[i].process): + for i in countup(0, gPassesLen - 1): + if not isNil(gPasses[i].process): m = gPasses[i].process(a[i], m) if isNil(m): return false result = true - -proc processTopLevelStmtCached(n: PNode, a: var TPassContextArray) = + +proc processTopLevelStmtCached(n: PNode, a: var TPassContextArray) = # this implements the code transformation pipeline var m = n - for i in countup(0, gPassesLen - 1): + for i in countup(0, gPassesLen - 1): if not isNil(gPasses[i].openCached): m = gPasses[i].process(a[i], m) - -proc closePassesCached(a: var TPassContextArray) = + +proc closePassesCached(a: var TPassContextArray) = var m: PNode = nil - for i in countup(0, gPassesLen - 1): - if not isNil(gPasses[i].openCached) and not isNil(gPasses[i].close): + for i in countup(0, gPassesLen - 1): + if not isNil(gPasses[i].openCached) and not isNil(gPasses[i].close): m = gPasses[i].close(a[i], m) a[i] = nil # free the memory here - + proc processImplicits(implicits: seq[string], nodeKind: TNodeKind, a: var TPassContextArray) = for module in items(implicits): @@ -159,45 +159,45 @@ proc processImplicits(implicits: seq[string], nodeKind: TNodeKind, str.info = gCmdLineInfo importStmt.addSon str if not processTopLevelStmt(importStmt, a): break - + proc processModule(module: PSym, stream: PLLStream, rd: PRodReader) = - var + var p: TParsers a: TPassContextArray s: PLLStream fileIdx = module.fileIdx - if rd == nil: + if rd == nil: openPasses(a, module) - if stream == nil: + if stream == nil: let filename = fileIdx.toFullPathConsiderDirty if module.name.s == "-": module.name.s = "stdinfile" s = llStreamOpen(stdin) else: s = llStreamOpen(filename, fmRead) - if s == nil: + if s == nil: rawMessage(errCannotOpenFile, filename) return else: s = stream - while true: + while true: openParsers(p, fileIdx, s) if sfSystemModule notin module.flags: - # XXX what about caching? no processing then? what if I change the + # XXX what about caching? no processing then? what if I change the # modules to include between compilation runs? we'd need to track that # in ROD files. I think we should enable this feature only # for the interactive mode. processImplicits implicitImports, nkImportStmt, a processImplicits implicitIncludes, nkIncludeStmt, a - while true: + while true: var n = parseTopLevelStmt(p) - if n.kind == nkEmpty: break + if n.kind == nkEmpty: break if not processTopLevelStmt(n, a): break closeParsers(p) - if s.kind != llsStdIn: break + if s.kind != llsStdIn: break closePasses(a) # id synchronization point for more consistent code generation: idSynchronizationPoint(1000) |