diff options
Diffstat (limited to 'compiler')
70 files changed, 525 insertions, 546 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index c8ce0dccb..8d52f12ff 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -10,8 +10,7 @@ # abstract syntax tree + symbol table import - lineinfos, hashes, nversion, options, strutils, std / sha1, ropes, idents, - intsets, idgen + lineinfos, hashes, options, ropes, idents, idgen type TCallingConvention* = enum diff --git a/compiler/ccgmerge.nim b/compiler/ccgmerge.nim index a0aa1b05d..cdb43f20f 100644 --- a/compiler/ccgmerge.nim +++ b/compiler/ccgmerge.nim @@ -11,8 +11,8 @@ ## is needed for incremental compilation. import - ast, astalgo, ropes, options, strutils, nimlexbase, msgs, cgendata, rodutils, - intsets, platform, llstream, tables, sighashes, modulegraphs, pathutils + ast, ropes, options, strutils, nimlexbase, cgendata, rodutils, + intsets, llstream, tables, modulegraphs, pathutils # Careful! Section marks need to contain a tabulator so that they cannot # be part of C string literals. diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim index 455012e60..3c7b0510e 100644 --- a/compiler/ccgutils.nim +++ b/compiler/ccgutils.nim @@ -10,7 +10,7 @@ # This module declares some helpers for the C code generator. import - ast, astalgo, ropes, hashes, strutils, types, msgs, wordrecg, + ast, hashes, strutils, msgs, wordrecg, platform, trees, options proc getPragmaStmt*(n: PNode, w: TSpecialWord): PNode = diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 4f136d9e3..d2ddd4a39 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -11,9 +11,9 @@ import ast, astalgo, hashes, trees, platform, magicsys, extccomp, options, intsets, - nversion, nimsets, msgs, std / sha1, bitsets, idents, types, + nversion, nimsets, msgs, bitsets, idents, types, ccgutils, os, ropes, math, passes, wordrecg, treetab, cgmeth, - condsyms, rodutils, renderer, idgen, cgendata, ccgmerge, semfold, aliases, + condsyms, rodutils, renderer, cgendata, ccgmerge, aliases, lowerings, tables, sets, ndi, lineinfos, pathutils, transf, enumtostr when not defined(leanCompiler): diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index 76c64782c..77445639e 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -10,7 +10,7 @@ ## This module contains the data structures for the C code generation phase. import - ast, astalgo, ropes, passes, options, intsets, platform, sighashes, + ast, ropes, passes, options, intsets, tables, ndi, lineinfos, pathutils, modulegraphs type diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index ab406bc4b..d83ca3c55 100644 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -10,7 +10,7 @@ ## This module implements code generation for multi methods. import - intsets, options, ast, astalgo, msgs, idents, renderer, types, magicsys, + intsets, options, ast, msgs, idents, renderer, types, magicsys, sempass2, strutils, modulegraphs, lineinfos proc genConv(n: PNode, d: PType, downcast: bool; conf: ConfigRef): PNode = diff --git a/compiler/closureiters.nim b/compiler/closureiters.nim index d1f2a6cd6..22595b772 100644 --- a/compiler/closureiters.nim +++ b/compiler/closureiters.nim @@ -131,8 +131,8 @@ # break :stateLoop import - intsets, strutils, options, ast, astalgo, trees, treetab, msgs, idents, - renderer, types, magicsys, lowerings, lambdalifting, modulegraphs, lineinfos + ast, msgs, idents, + renderer, magicsys, lowerings, lambdalifting, modulegraphs, lineinfos type Ctx = object diff --git a/compiler/commands.nim b/compiler/commands.nim index ff76fff71..ed0320a7c 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -27,7 +27,7 @@ bootSwitch(usedNoGC, defined(nogc), "--gc:none") import os, msgs, options, nversion, condsyms, strutils, extccomp, platform, - wordrecg, parseutils, nimblecmd, idents, parseopt, sequtils, lineinfos, + wordrecg, parseutils, nimblecmd, parseopt, sequtils, lineinfos, pathutils, strtabs # but some have deps to imported modules. Yay. diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index ed95c8183..ce295c8b9 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -10,7 +10,7 @@ # This module handles the conditional symbols. import - strtabs, platform, strutils, idents + strtabs from options import Feature from lineinfos import HintsToStr, WarningsToStr diff --git a/compiler/depends.nim b/compiler/depends.nim index 300ab3b54..603f67e77 100644 --- a/compiler/depends.nim +++ b/compiler/depends.nim @@ -10,8 +10,7 @@ # This module implements a dependency file generator. import - os, options, ast, astalgo, msgs, ropes, idents, passes, modulepaths, - pathutils + options, ast, ropes, idents, passes, modulepaths, pathutils from modulegraphs import ModuleGraph, PPassContext diff --git a/compiler/dfa.nim b/compiler/dfa.nim index f97d8f298..7315e74bc 100644 --- a/compiler/dfa.nim +++ b/compiler/dfa.nim @@ -29,7 +29,7 @@ ## "A Graph–Free Approach to Data–Flow Analysis" by Markus Mohnen. ## https://link.springer.com/content/pdf/10.1007/3-540-45937-5_6.pdf -import ast, astalgo, types, intsets, tables, msgs, options, lineinfos, renderer +import ast, types, intsets, lineinfos, renderer from patterns import sameTrees diff --git a/compiler/docgen.nim b/compiler/docgen.nim index a98360c07..2e03c0d4d 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -16,7 +16,7 @@ import wordrecg, syntaxes, renderer, lexer, packages/docutils/rstast, packages/docutils/rst, packages/docutils/rstgen, packages/docutils/highlite, json, xmltree, cgi, trees, types, - typesrenderer, astalgo, modulepaths, lineinfos, sequtils, intsets, + typesrenderer, astalgo, modulepaths, lineinfos, intsets, pathutils, trees const diff --git a/compiler/docgen2.nim b/compiler/docgen2.nim index 048860423..e19b3a989 100644 --- a/compiler/docgen2.nim +++ b/compiler/docgen2.nim @@ -11,8 +11,7 @@ # semantic checking. import - os, options, ast, astalgo, msgs, ropes, idents, passes, docgen, lineinfos, - pathutils + options, ast, msgs, idents, passes, docgen, lineinfos, pathutils from modulegraphs import ModuleGraph, PPassContext diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index 8acb85907..d3d3e5f77 100644 --- a/compiler/evaltempl.nim +++ b/compiler/evaltempl.nim @@ -10,8 +10,7 @@ ## Template evaluation engine. Now hygienic. import - strutils, options, ast, astalgo, msgs, os, idents, wordrecg, renderer, - lineinfos + strutils, options, ast, astalgo, msgs, renderer, lineinfos type TemplCtx = object diff --git a/compiler/filter_tmpl.nim b/compiler/filter_tmpl.nim index b884b1ec3..490c184cf 100644 --- a/compiler/filter_tmpl.nim +++ b/compiler/filter_tmpl.nim @@ -10,8 +10,8 @@ # This module implements Nim's standard template filter. import - llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options, - renderer, filters, lineinfos, pathutils + llstream, strutils, ast, msgs, options, + filters, lineinfos, pathutils type TParseState = enum diff --git a/compiler/filters.nim b/compiler/filters.nim index c04d61320..a2f7b6bbb 100644 --- a/compiler/filters.nim +++ b/compiler/filters.nim @@ -10,7 +10,7 @@ # This module implements Nim's simple filters and helpers for filters. import - llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options, + llstream, idents, strutils, ast, msgs, options, renderer, pathutils proc invalidPragma(conf: ConfigRef; n: PNode) = diff --git a/compiler/gorgeimpl.nim b/compiler/gorgeimpl.nim index d61dcdac3..c9f82b505 100644 --- a/compiler/gorgeimpl.nim +++ b/compiler/gorgeimpl.nim @@ -9,7 +9,7 @@ ## Module that implements ``gorge`` for the compiler. -import msgs, std / sha1, os, osproc, streams, strutils, options, +import msgs, std / sha1, os, osproc, streams, options, lineinfos, pathutils proc readOutput(p: Process): (string, int) = diff --git a/compiler/idents.nim b/compiler/idents.nim index f82ff5db5..3153745d5 100644 --- a/compiler/idents.nim +++ b/compiler/idents.nim @@ -12,7 +12,7 @@ # id. This module is essential for the compiler's performance. import - hashes, strutils, wordrecg + hashes, wordrecg type TIdObj* = object of RootObj diff --git a/compiler/idgen.nim b/compiler/idgen.nim index 239df0c57..7d49e33e3 100644 --- a/compiler/idgen.nim +++ b/compiler/idgen.nim @@ -9,7 +9,7 @@ ## This module contains a simple persistent id generator. -import idents, strutils, os, options, pathutils +import idents, strutils, options, pathutils var gFrontEndId*: int diff --git a/compiler/importer.nim b/compiler/importer.nim index ec065a1ec..2a5a1ac7c 100644 --- a/compiler/importer.nim +++ b/compiler/importer.nim @@ -10,8 +10,8 @@ ## This module implements the symbol importing mechanism. import - intsets, strutils, os, ast, astalgo, msgs, options, idents, lookups, - semdata, passes, renderer, modulepaths, sigmatch, lineinfos + intsets, ast, astalgo, msgs, options, idents, lookups, + semdata, modulepaths, sigmatch, lineinfos proc readExceptSet*(c: PContext, n: PNode): IntSet = assert n.kind in {nkImportExceptStmt, nkExportExceptStmt} diff --git a/compiler/incremental.nim b/compiler/incremental.nim index f66a75efd..29528bbd3 100644 --- a/compiler/incremental.nim +++ b/compiler/incremental.nim @@ -12,10 +12,10 @@ const nimIncremental* = defined(nimIncremental) -import options, lineinfos, pathutils +import options, lineinfos when nimIncremental: - import ast, msgs, intsets, btrees, db_sqlite, std / sha1 + import ast, msgs, intsets, btrees, db_sqlite, std / sha1, pathutils from strutils import parseInt type diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index a8a2cf97f..6f1da37fb 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -134,7 +134,7 @@ to do it. ]# import - intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees, + intsets, ast, msgs, renderer, magicsys, types, idents, strutils, options, dfa, lowerings, tables, modulegraphs, msgs, lineinfos, parampatterns, sighashes diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 0c04b339c..788e3e75b 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -29,11 +29,11 @@ implements the required case distinction. import - ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp, options, - nversion, nimsets, msgs, std / sha1, bitsets, idents, types, os, tables, - times, ropes, math, passes, ccgutils, wordrecg, renderer, + ast, strutils, trees, magicsys, options, + nversion, msgs, idents, types, tables, + ropes, math, passes, ccgutils, wordrecg, renderer, intsets, cgmeth, lowerings, sighashes, modulegraphs, lineinfos, rodutils, - pathutils, transf + transf from modulegraphs import ModuleGraph, PPassContext diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index 6d87444ec..679391224 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -10,7 +10,7 @@ # This file implements lambda lifting for the transformator. import - intsets, strutils, options, ast, astalgo, trees, treetab, msgs, + intsets, strutils, options, ast, astalgo, msgs, idents, renderer, types, magicsys, lowerings, tables, modulegraphs, lineinfos, transf, liftdestructors diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim index 97c2636ac..5619350ef 100644 --- a/compiler/liftdestructors.nim +++ b/compiler/liftdestructors.nim @@ -13,7 +13,7 @@ # Todo: # - use openArray instead of array to avoid over-specializations -import modulegraphs, lineinfos, idents, ast, astalgo, renderer, semdata, +import modulegraphs, lineinfos, idents, ast, renderer, semdata, sighashes, lowerings, options, types, msgs, magicsys, tables type diff --git a/compiler/liftlocals.nim b/compiler/liftlocals.nim index ae789cd88..eed0560ab 100644 --- a/compiler/liftlocals.nim +++ b/compiler/liftlocals.nim @@ -10,7 +10,7 @@ ## This module implements the '.liftLocals' pragma. import - intsets, strutils, options, ast, astalgo, msgs, + strutils, options, ast, msgs, idents, renderer, types, lowerings, lineinfos from pragmas import getPragmaVal diff --git a/compiler/linter.nim b/compiler/linter.nim index abefe9bec..d3c461b66 100644 --- a/compiler/linter.nim +++ b/compiler/linter.nim @@ -9,11 +9,9 @@ ## This module implements the style checker. -import - strutils, os, intsets, strtabs +import strutils -import options, ast, astalgo, msgs, semdata, ropes, idents, - lineinfos, pathutils, wordrecg +import options, ast, msgs, idents, lineinfos, wordrecg const Letters* = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '_'} diff --git a/compiler/llstream.nim b/compiler/llstream.nim index 9cbca4c4b..ab4e1645c 100644 --- a/compiler/llstream.nim +++ b/compiler/llstream.nim @@ -10,7 +10,7 @@ ## Low-level streams for high performance. import - strutils, pathutils + pathutils # support '-d:useGnuReadline' for backwards compatibility: when not defined(windows) and (defined(useGnuReadline) or defined(useLinenoise)): diff --git a/compiler/lookups.nim b/compiler/lookups.nim index 7c37817fd..4de1fc371 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -11,7 +11,7 @@ import intsets, ast, astalgo, idents, semdata, types, msgs, options, - renderer, wordrecg, idgen, nimfix/prettybase, lineinfos, strutils + renderer, nimfix/prettybase, lineinfos, strutils proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope) diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index 0030f1a49..727b88760 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -14,7 +14,6 @@ const import ast, astalgo, types, idents, magicsys, msgs, options, modulegraphs, lineinfos -from trees import getMagic proc newDeref*(n: PNode): PNode {.inline.} = result = newNodeIT(nkHiddenDeref, n.info, n.typ.sons[0]) diff --git a/compiler/macrocacheimpl.nim b/compiler/macrocacheimpl.nim index d23040763..365497e31 100644 --- a/compiler/macrocacheimpl.nim +++ b/compiler/macrocacheimpl.nim @@ -9,7 +9,7 @@ ## This module implements helpers for the macro cache. -import lineinfos, ast, modulegraphs, vmdef, magicsys +import lineinfos, ast, modulegraphs, vmdef proc recordInc*(c: PCtx; info: TLineInfo; key: string; by: BiggestInt) = var recorded = newNodeI(nkCommentStmt, info) diff --git a/compiler/magicsys.nim b/compiler/magicsys.nim index aeeb489c0..38240061f 100644 --- a/compiler/magicsys.nim +++ b/compiler/magicsys.nim @@ -10,7 +10,7 @@ # Built-in types and compilerprocs are registered here. import - ast, astalgo, hashes, msgs, platform, nversion, times, idents, + ast, astalgo, msgs, platform, idents, modulegraphs, lineinfos export createMagic diff --git a/compiler/main.nim b/compiler/main.nim index 460fd90c7..ce80af36d 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -13,12 +13,12 @@ when not defined(nimcore): {.error: "nimcore MUST be defined for Nim's core tooling".} import - llstream, strutils, ast, astalgo, lexer, syntaxes, renderer, options, msgs, - os, condsyms, times, - wordrecg, sem, semdata, idents, passes, extccomp, + llstream, strutils, ast, lexer, syntaxes, options, msgs, + condsyms, times, + sem, idents, passes, extccomp, cgen, json, nversion, - platform, nimconf, importer, passaux, depends, vm, vmdef, types, idgen, - parser, modules, ccgutils, sigmatch, ropes, + platform, nimconf, passaux, depends, vm, idgen, + parser, modules, modulegraphs, tables, rod, lineinfos, pathutils when not defined(leanCompiler): diff --git a/compiler/modulepaths.nim b/compiler/modulepaths.nim index 6130c3032..eedb22084 100644 --- a/compiler/modulepaths.nim +++ b/compiler/modulepaths.nim @@ -8,7 +8,7 @@ # import ast, renderer, strutils, msgs, options, idents, os, lineinfos, - pathutils, nimblecmd + pathutils when false: const diff --git a/compiler/modules.nim b/compiler/modules.nim index 3dbc1b2c1..40d9a904c 100644 --- a/compiler/modules.nim +++ b/compiler/modules.nim @@ -10,8 +10,8 @@ ## Implements the module handling, including the caching of modules. import - ast, astalgo, magicsys, std / sha1, msgs, cgendata, sigmatch, options, - idents, os, lexer, idgen, passes, syntaxes, llstream, modulegraphs, rod, + ast, astalgo, magicsys, msgs, options, + idents, lexer, idgen, passes, syntaxes, llstream, modulegraphs, rod, lineinfos, pathutils, tables proc resetSystemArtifacts*(g: ModuleGraph) = diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 03b6213fa..1264133a9 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -8,7 +8,7 @@ # import - options, strutils, os, tables, ropes, platform, terminal, macros, + options, strutils, os, tables, ropes, terminal, macros, lineinfos, pathutils proc toCChar*(c: char; result: var string) = diff --git a/compiler/nim.nim b/compiler/nim.nim index 5fcf043b5..ec7e8b8dc 100644 --- a/compiler/nim.nim +++ b/compiler/nim.nim @@ -19,9 +19,9 @@ when defined(i386) and defined(windows) and defined(vcc): {.link: "../icons/nim-i386-windows-vcc.res".} import - commands, lexer, condsyms, options, msgs, nversion, nimconf, ropes, - extccomp, strutils, os, osproc, platform, main, parseopt, - scriptconfig, idents, modulegraphs, lineinfos, cmdlinehelper, + commands, options, msgs, + extccomp, strutils, os, main, parseopt, + idents, lineinfos, cmdlinehelper, pathutils include nodejs diff --git a/compiler/nimconf.nim b/compiler/nimconf.nim index f518b3abf..a470179bd 100644 --- a/compiler/nimconf.nim +++ b/compiler/nimconf.nim @@ -10,7 +10,7 @@ # This module handles the reading of the config file. import - llstream, nversion, commands, os, strutils, msgs, platform, condsyms, lexer, + llstream, commands, os, strutils, msgs, lexer, options, idents, wordrecg, strtabs, lineinfos, pathutils # ---------------- configuration file parser ----------------------------- diff --git a/compiler/nimfix/prettybase.nim b/compiler/nimfix/prettybase.nim index c3e16e5ba..fbc2e3bd1 100644 --- a/compiler/nimfix/prettybase.nim +++ b/compiler/nimfix/prettybase.nim @@ -8,9 +8,7 @@ # import strutils except Letters -import lexbase, streams import ".." / [ast, msgs, lineinfos, idents, options, linter] -from os import splitFile proc replaceDeprecated*(conf: ConfigRef; info: TLineInfo; oldSym, newSym: PIdent) = let line = sourceLine(conf, info) diff --git a/compiler/nimsets.nim b/compiler/nimsets.nim index c2436dff0..f4ef0cc39 100644 --- a/compiler/nimsets.nim +++ b/compiler/nimsets.nim @@ -10,8 +10,7 @@ # this unit handles Nim sets; it implements symbolic sets import - ast, astalgo, trees, nversion, lineinfos, platform, bitsets, types, renderer, - options + ast, astalgo, lineinfos, bitsets, types, options proc inSet*(s: PNode, elem: PNode): bool = assert s.kind == nkCurly diff --git a/compiler/options.nim b/compiler/options.nim index 985955d98..6303224a2 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -8,7 +8,7 @@ # import - os, strutils, strtabs, osproc, sets, lineinfos, platform, + os, strutils, strtabs, sets, lineinfos, platform, prefixmatches, pathutils from terminal import isatty diff --git a/compiler/parampatterns.nim b/compiler/parampatterns.nim index b4409fcec..1bd703fe8 100644 --- a/compiler/parampatterns.nim +++ b/compiler/parampatterns.nim @@ -10,7 +10,7 @@ ## This module implements the pattern matching features for term rewriting ## macro support. -import strutils, ast, astalgo, types, msgs, idents, renderer, wordrecg, trees, +import strutils, ast, types, msgs, idents, renderer, wordrecg, trees, options # we precompile the pattern here for efficiency into some internal diff --git a/compiler/parser.nim b/compiler/parser.nim index 12036f20b..74d633814 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -27,7 +27,7 @@ when isMainModule: outp.close import - llstream, lexer, idents, strutils, ast, astalgo, msgs, options, lineinfos, + llstream, lexer, idents, strutils, ast, msgs, options, lineinfos, pathutils when defined(nimpretty): diff --git a/compiler/passaux.nim b/compiler/passaux.nim index 17c4c506a..2ac89c24e 100644 --- a/compiler/passaux.nim +++ b/compiler/passaux.nim @@ -10,7 +10,7 @@ ## implements some little helper passes import - strutils, ast, astalgo, passes, idents, msgs, options, idgen, lineinfos + ast, passes, idents, msgs, options, idgen, lineinfos from modulegraphs import ModuleGraph, PPassContext diff --git a/compiler/passes.nim b/compiler/passes.nim index 72140d9de..7effcfeb5 100644 --- a/compiler/passes.nim +++ b/compiler/passes.nim @@ -11,9 +11,9 @@ ## `TPass` interface. import - strutils, options, ast, astalgo, llstream, msgs, platform, os, - condsyms, idents, renderer, types, extccomp, math, magicsys, nversion, - nimsets, syntaxes, times, idgen, modulegraphs, reorder, rod, + options, ast, llstream, msgs, + idents, + syntaxes, idgen, modulegraphs, reorder, rod, lineinfos, pathutils type diff --git a/compiler/pathutils.nim b/compiler/pathutils.nim index cd6fb2a53..b73942a21 100644 --- a/compiler/pathutils.nim +++ b/compiler/pathutils.nim @@ -10,7 +10,7 @@ ## Path handling utilities for Nim. Strictly typed code in order ## to avoid the never ending time sink in getting path handling right. -import os, strutils, pathnorm +import os, pathnorm type AbsoluteFile* = distinct string diff --git a/compiler/patterns.nim b/compiler/patterns.nim index d9a6e7d1d..e20c42b66 100644 --- a/compiler/patterns.nim +++ b/compiler/patterns.nim @@ -11,8 +11,7 @@ ## macro support. import - ast, astalgo, types, semdata, sigmatch, msgs, idents, aliases, parampatterns, - trees + ast, types, semdata, sigmatch, idents, aliases, parampatterns, trees type TPatternContext = object diff --git a/compiler/plugins/itersgen.nim b/compiler/plugins/itersgen.nim index 440d2e081..e4b3a5029 100644 --- a/compiler/plugins/itersgen.nim +++ b/compiler/plugins/itersgen.nim @@ -9,9 +9,7 @@ ## Plugin to transform an inline iterator into a data structure. -import ".." / [ast, astalgo, - magicsys, lookups, semdata, - lambdalifting, msgs] +import ".." / [ast, lookups, semdata, lambdalifting, msgs] proc iterToProcImpl*(c: PContext, n: PNode): PNode = result = newNodeI(nkStmtList, n.info) diff --git a/compiler/plugins/locals.nim b/compiler/plugins/locals.nim index eb3324b36..08d836f7d 100644 --- a/compiler/plugins/locals.nim +++ b/compiler/plugins/locals.nim @@ -9,7 +9,7 @@ ## The builtin 'system.locals' implemented as a plugin. -import ".." / [pluginsupport, ast, astalgo, +import ".." / [ast, astalgo, magicsys, lookups, semdata, lowerings] proc semLocals*(c: PContext, n: PNode): PNode = diff --git a/compiler/reorder.nim b/compiler/reorder.nim index e341885ee..960929811 100644 --- a/compiler/reorder.nim +++ b/compiler/reorder.nim @@ -1,7 +1,7 @@ import - intsets, ast, idents, algorithm, renderer, parser, os, strutils, - sequtils, msgs, modulegraphs, syntaxes, options, modulepaths, tables, + intsets, ast, idents, algorithm, renderer, os, strutils, + msgs, modulegraphs, syntaxes, options, modulepaths, lineinfos type diff --git a/compiler/rod.nim b/compiler/rod.nim index bbd2f0c6c..e3e568a0e 100644 --- a/compiler/rod.nim +++ b/compiler/rod.nim @@ -9,7 +9,7 @@ ## This module implements the canonalization for the various caching mechanisms. -import ast, idgen, lineinfos, msgs, incremental, modulegraphs, pathutils +import ast, idgen, lineinfos, incremental, modulegraphs, pathutils when not nimIncremental: template setupModuleCache*(g: ModuleGraph) = discard diff --git a/compiler/scriptconfig.nim b/compiler/scriptconfig.nim index 6c3d0a122..9878cf597 100644 --- a/compiler/scriptconfig.nim +++ b/compiler/scriptconfig.nim @@ -11,9 +11,10 @@ ## language. import - ast, modules, idents, passes, passaux, condsyms, - options, nimconf, sem, semdata, llstream, vm, vmdef, commands, msgs, - os, times, osproc, wordrecg, strtabs, modulegraphs, lineinfos, pathutils + ast, modules, idents, passes, condsyms, + options, sem, llstream, vm, vmdef, commands, msgs, + os, times, osproc, wordrecg, strtabs, modulegraphs, + lineinfos, pathutils # we support 'cmpIgnoreStyle' natively for efficiency: from strutils import cmpIgnoreStyle, contains diff --git a/compiler/sem.nim b/compiler/sem.nim index 95c22e549..fa0f742f7 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -10,13 +10,13 @@ # This module implements the semantic checking pass. import - ast, strutils, hashes, options, lexer, astalgo, trees, treetab, - wordrecg, ropes, msgs, os, condsyms, idents, renderer, types, platform, math, - magicsys, parser, nversion, nimsets, semfold, modulepaths, importer, + ast, strutils, options, astalgo, trees, + wordrecg, ropes, msgs, idents, renderer, types, platform, math, + magicsys, nversion, nimsets, semfold, modulepaths, importer, procfind, lookups, pragmas, passes, semdata, semtypinst, sigmatch, intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting, evaltempl, patterns, parampatterns, sempass2, linter, semmacrosanity, - lowerings, pluginsupport, plugins/active, rod, lineinfos, strtabs, int128 + lowerings, plugins/active, rod, lineinfos, strtabs, int128 from modulegraphs import ModuleGraph, PPassContext, onUse, onDef, onDefResolveForward diff --git a/compiler/semdata.nim b/compiler/semdata.nim index e411633c2..6c7dd02ed 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -10,11 +10,8 @@ ## This module contains the data structures for the semantic checking phase. import - strutils, intsets, options, lexer, ast, astalgo, trees, treetab, - wordrecg, - ropes, msgs, platform, os, condsyms, idents, renderer, types, extccomp, math, - magicsys, nversion, nimsets, parser, times, passes, vmdef, - modulegraphs, lineinfos + intsets, options, ast, astalgo, msgs, idents, renderer, + magicsys, passes, vmdef, modulegraphs, lineinfos type TOptionEntry* = object # entries to put on a stack for pragma parsing diff --git a/compiler/semfold.nim b/compiler/semfold.nim index 2f07940c8..c7efa1a87 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -11,8 +11,8 @@ # and evaluation phase import - strutils, options, ast, astalgo, trees, treetab, nimsets, - nversion, platform, math, msgs, os, condsyms, idents, renderer, types, + strutils, options, ast, trees, nimsets, + platform, math, msgs, idents, renderer, types, commands, magicsys, modulegraphs, strtabs, lineinfos proc newIntNodeT*(intVal: BiggestInt, n: PNode; g: ModuleGraph): PNode = diff --git a/compiler/semmacrosanity.nim b/compiler/semmacrosanity.nim index faf3e3868..af740e518 100644 --- a/compiler/semmacrosanity.nim +++ b/compiler/semmacrosanity.nim @@ -10,7 +10,7 @@ ## Implements type sanity checking for ASTs resulting from macros. Lots of ## room for improvement here. -import ast, astalgo, msgs, types, options +import ast, msgs, types, options proc ithField(n: PNode, field: var int): PSym = result = nil diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 0e1c9cb07..8252a7857 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -10,7 +10,7 @@ import intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees, wordrecg, strutils, options, guards, lineinfos, semfold, semdata, - modulegraphs, lowerings, sigmatch, tables + modulegraphs when not defined(leanCompiler): import writetracking diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim index c69797391..a9d911e27 100644 --- a/compiler/sighashes.nim +++ b/compiler/sighashes.nim @@ -11,9 +11,7 @@ import ast, tables, ropes, md5, modulegraphs from hashes import Hash -from astalgo import debug import types -from strutils import startsWith, contains proc `&=`(c: var MD5Context, s: string) = md5Update(c, s, s.len) proc `&=`(c: var MD5Context, ch: char) = md5Update(c, unsafeAddr ch, 1) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 9f24dd3c2..b331b6f1f 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -12,7 +12,7 @@ import intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst, - magicsys, condsyms, idents, lexer, options, parampatterns, strutils, trees, + magicsys, idents, lexer, options, parampatterns, strutils, trees, linter, lineinfos, lowerings, modulegraphs when (defined(booting) or defined(nimsuggest)) and not defined(leanCompiler): diff --git a/compiler/spawn.nim b/compiler/spawn.nim index b8477567b..733ce7732 100644 --- a/compiler/spawn.nim +++ b/compiler/spawn.nim @@ -1,428 +1,428 @@ -# -# -# The Nim Compiler -# (c) Copyright 2015 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## This module implements threadpool's ``spawn``. - -import ast, astalgo, types, idents, magicsys, msgs, options, modulegraphs, - lineinfos, lowerings -from trees import getMagic - -proc callProc(a: PNode): PNode = - result = newNodeI(nkCall, a.info) - result.add a - result.typ = a.typ.sons[0] - -# we have 4 cases to consider: -# - a void proc --> nothing to do -# - a proc returning GC'ed memory --> requires a flowVar -# - a proc returning non GC'ed memory --> pass as hidden 'var' parameter -# - not in a parallel environment --> requires a flowVar for memory safety -type - TSpawnResult* = enum - srVoid, srFlowVar, srByVar - TFlowVarKind = enum - fvInvalid # invalid type T for 'FlowVar[T]' - fvGC # FlowVar of a GC'ed type - fvBlob # FlowVar of a blob type - -proc spawnResult*(t: PType; inParallel: bool): TSpawnResult = - if t.isEmptyType: srVoid - elif inParallel and not containsGarbageCollectedRef(t): srByVar - else: srFlowVar - -proc flowVarKind(t: PType): TFlowVarKind = - if t.skipTypes(abstractInst).kind in {tyRef, tyString, tySequence}: fvGC - elif containsGarbageCollectedRef(t): fvInvalid - else: fvBlob - -proc typeNeedsNoDeepCopy(t: PType): bool = - var t = t.skipTypes(abstractInst) - # for the tconvexhull example (and others) we're a bit lax here and pretend - # seqs and strings are *by value* only and 'shallow' doesn't exist! - if t.kind == tyString: return true - # note that seq[T] is fine, but 'var seq[T]' is not, so we need to skip 'var' - # for the stricter check and likewise we can skip 'seq' for a less - # strict check: - if t.kind in {tyVar, tyLent, tySequence}: t = t.lastSon - result = not containsGarbageCollectedRef(t) - -proc addLocalVar(g: ModuleGraph; varSection, varInit: PNode; owner: PSym; typ: PType; - v: PNode; useShallowCopy=false): PSym = - result = newSym(skTemp, getIdent(g.cache, genPrefix), owner, varSection.info, - owner.options) - result.typ = typ - incl(result.flags, sfFromGeneric) - - var vpart = newNodeI(nkIdentDefs, varSection.info, 3) - vpart.sons[0] = newSymNode(result) - vpart.sons[1] = newNodeI(nkEmpty, varSection.info) - vpart.sons[2] = if varInit.isNil: v else: vpart[1] - varSection.add vpart - if varInit != nil: - if useShallowCopy and typeNeedsNoDeepCopy(typ): - varInit.add newFastAsgnStmt(newSymNode(result), v) - else: - let deepCopyCall = newNodeI(nkCall, varInit.info, 3) - deepCopyCall.sons[0] = newSymNode(getSysMagic(g, varSection.info, "deepCopy", mDeepCopy)) - deepCopyCall.sons[1] = newSymNode(result) - deepCopyCall.sons[2] = v - varInit.add deepCopyCall - -discard """ -We generate roughly this: - -proc f_wrapper(thread, args) = - barrierEnter(args.barrier) # for parallel statement - var a = args.a # thread transfer; deepCopy or shallowCopy or no copy - # depending on whether we're in a 'parallel' statement - var b = args.b - var fv = args.fv - - fv.owner = thread # optional - nimArgsPassingDone() # signal parent that the work is done - # - args.fv.blob = f(a, b, ...) - nimFlowVarSignal(args.fv) - - # - or - - f(a, b, ...) - barrierLeave(args.barrier) # for parallel statement - -stmtList: - var scratchObj - scratchObj.a = a - scratchObj.b = b - - nimSpawn(f_wrapper, addr scratchObj) - scratchObj.fv # optional - -""" - -proc createWrapperProc(g: ModuleGraph; f: PNode; threadParam, argsParam: PSym; - varSection, varInit, call, barrier, fv: PNode; - spawnKind: TSpawnResult): PSym = - var body = newNodeI(nkStmtList, f.info) - body.flags.incl nfTransf # do not transform further - - var threadLocalBarrier: PSym - if barrier != nil: - var varSection2 = newNodeI(nkVarSection, barrier.info) - threadLocalBarrier = addLocalVar(g, varSection2, nil, argsParam.owner, - barrier.typ, barrier) - body.add varSection2 - body.add callCodegenProc(g, "barrierEnter", threadLocalBarrier.info, - threadLocalBarrier.newSymNode) - var threadLocalProm: PSym - if spawnKind == srByVar: - threadLocalProm = addLocalVar(g, varSection, nil, argsParam.owner, fv.typ, fv) - elif fv != nil: - internalAssert g.config, fv.typ.kind == tyGenericInst - threadLocalProm = addLocalVar(g, varSection, nil, argsParam.owner, fv.typ, fv) - body.add varSection - body.add varInit - if fv != nil and spawnKind != srByVar: - # generate: - # fv.owner = threadParam - body.add newAsgnStmt(indirectAccess(threadLocalProm.newSymNode, - "owner", fv.info, g.cache), threadParam.newSymNode) - - body.add callCodegenProc(g, "nimArgsPassingDone", threadParam.info, - threadParam.newSymNode) - if spawnKind == srByVar: - body.add newAsgnStmt(genDeref(threadLocalProm.newSymNode), call) - elif fv != nil: - let fk = fv.typ.sons[1].flowVarKind - if fk == fvInvalid: - localError(g.config, f.info, "cannot create a flowVar of type: " & - typeToString(fv.typ.sons[1])) - body.add newAsgnStmt(indirectAccess(threadLocalProm.newSymNode, - if fk == fvGC: "data" else: "blob", fv.info, g.cache), call) - if fk == fvGC: - let incRefCall = newNodeI(nkCall, fv.info, 2) - incRefCall.sons[0] = newSymNode(getSysMagic(g, fv.info, "GCref", mGCref)) - incRefCall.sons[1] = indirectAccess(threadLocalProm.newSymNode, - "data", fv.info, g.cache) - body.add incRefCall - if barrier == nil: - # by now 'fv' is shared and thus might have beeen overwritten! we need - # to use the thread-local view instead: - body.add callCodegenProc(g, "nimFlowVarSignal", threadLocalProm.info, - threadLocalProm.newSymNode) - else: - body.add call - if barrier != nil: - body.add callCodegenProc(g, "barrierLeave", threadLocalBarrier.info, - threadLocalBarrier.newSymNode) - - var params = newNodeI(nkFormalParams, f.info) - params.add newNodeI(nkEmpty, f.info) - params.add threadParam.newSymNode - params.add argsParam.newSymNode - - var t = newType(tyProc, threadParam.owner) - t.rawAddSon nil - t.rawAddSon threadParam.typ - t.rawAddSon argsParam.typ - t.n = newNodeI(nkFormalParams, f.info) - t.n.add newNodeI(nkEffectList, f.info) - t.n.add threadParam.newSymNode - t.n.add argsParam.newSymNode - - let name = (if f.kind == nkSym: f.sym.name.s else: genPrefix) & "Wrapper" - result = newSym(skProc, getIdent(g.cache, name), argsParam.owner, f.info, - argsParam.options) - let emptyNode = newNodeI(nkEmpty, f.info) - result.ast = newProcNode(nkProcDef, f.info, body = body, - params = params, name = newSymNode(result), pattern = emptyNode, - genericParams = emptyNode, pragmas = emptyNode, - exceptions = emptyNode) - result.typ = t - -proc createCastExpr(argsParam: PSym; objType: PType): PNode = - result = newNodeI(nkCast, argsParam.info) - result.add newNodeI(nkEmpty, argsParam.info) - result.add newSymNode(argsParam) - result.typ = newType(tyPtr, objType.owner) - result.typ.rawAddSon(objType) - -proc setupArgsForConcurrency(g: ModuleGraph; n: PNode; objType: PType; scratchObj: PSym, - castExpr, call, - varSection, varInit, result: PNode) = - let formals = n[0].typ.n - let tmpName = getIdent(g.cache, genPrefix) - for i in 1 ..< n.len: - # we pick n's type here, which hopefully is 'tyArray' and not - # 'tyOpenArray': - var argType = n[i].typ.skipTypes(abstractInst) - if i < formals.len and formals[i].typ.kind in {tyVar, tyLent}: - localError(g.config, n[i].info, "'spawn'ed function cannot have a 'var' parameter") - #elif containsTyRef(argType): - # localError(n[i].info, "'spawn'ed function cannot refer to 'ref'/closure") - - let fieldname = if i < formals.len: formals[i].sym.name else: tmpName - var field = newSym(skField, fieldname, objType.owner, n.info, g.config.options) - field.typ = argType - objType.addField(field, g.cache) - result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n[i]) - - let temp = addLocalVar(g, varSection, varInit, objType.owner, argType, - indirectAccess(castExpr, field, n.info)) - call.add(newSymNode(temp)) - -proc getRoot*(n: PNode): PSym = - ## ``getRoot`` takes a *path* ``n``. A path is an lvalue expression - ## like ``obj.x[i].y``. The *root* of a path is the symbol that can be - ## determined as the owner; ``obj`` in the example. - case n.kind - of nkSym: - if n.sym.kind in {skVar, skResult, skTemp, skLet, skForVar}: - result = n.sym - of nkDotExpr, nkBracketExpr, nkHiddenDeref, nkDerefExpr, - nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr: - result = getRoot(n.sons[0]) - of nkHiddenStdConv, nkHiddenSubConv, nkConv: - result = getRoot(n.sons[1]) - of nkCallKinds: - if getMagic(n) == mSlice: result = getRoot(n.sons[1]) - else: discard - -proc setupArgsForParallelism(g: ModuleGraph; n: PNode; objType: PType; scratchObj: PSym; - castExpr, call, - varSection, varInit, result: PNode) = - let formals = n[0].typ.n - let tmpName = getIdent(g.cache, genPrefix) - # we need to copy the foreign scratch object fields into local variables - # for correctness: These are called 'threadLocal' here. - for i in 1 ..< n.len: - let n = n[i] - let argType = skipTypes(if i < formals.len: formals[i].typ else: n.typ, - abstractInst) - #if containsTyRef(argType): - # localError(n.info, "'spawn'ed function cannot refer to 'ref'/closure") - - let fieldname = if i < formals.len: formals[i].sym.name else: tmpName - var field = newSym(skField, fieldname, objType.owner, n.info, g.config.options) - - if argType.kind in {tyVarargs, tyOpenArray}: - # important special case: we always create a zero-copy slice: - let slice = newNodeI(nkCall, n.info, 4) - slice.typ = n.typ - slice.sons[0] = newSymNode(createMagic(g, "slice", mSlice)) - slice.sons[0].typ = getSysType(g, n.info, tyInt) # fake type - var fieldB = newSym(skField, tmpName, objType.owner, n.info, g.config.options) - fieldB.typ = getSysType(g, n.info, tyInt) - objType.addField(fieldB, g.cache) - - if getMagic(n) == mSlice: - let a = genAddrOf(n[1]) - field.typ = a.typ - objType.addField(field, g.cache) - result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a) - - var fieldA = newSym(skField, tmpName, objType.owner, n.info, g.config.options) - fieldA.typ = getSysType(g, n.info, tyInt) - objType.addField(fieldA, g.cache) - result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldA), n[2]) - result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldB), n[3]) - - let threadLocal = addLocalVar(g, varSection,nil, objType.owner, fieldA.typ, - indirectAccess(castExpr, fieldA, n.info), - useShallowCopy=true) - slice.sons[2] = threadLocal.newSymNode - else: - let a = genAddrOf(n) - field.typ = a.typ - objType.addField(field, g.cache) - result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a) - result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldB), genHigh(g, n)) - - slice.sons[2] = newIntLit(g, n.info, 0) - # the array itself does not need to go through a thread local variable: - slice.sons[1] = genDeref(indirectAccess(castExpr, field, n.info)) - - let threadLocal = addLocalVar(g, varSection,nil, objType.owner, fieldB.typ, - indirectAccess(castExpr, fieldB, n.info), - useShallowCopy=true) - slice.sons[3] = threadLocal.newSymNode - call.add slice - elif (let size = computeSize(g.config, argType); size < 0 or size > 16) and - n.getRoot != nil: - # it is more efficient to pass a pointer instead: - let a = genAddrOf(n) - field.typ = a.typ - objType.addField(field, g.cache) - result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a) - let threadLocal = addLocalVar(g, varSection,nil, objType.owner, field.typ, - indirectAccess(castExpr, field, n.info), - useShallowCopy=true) - call.add(genDeref(threadLocal.newSymNode)) - else: - # boring case - field.typ = argType - objType.addField(field, g.cache) - result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n) - let threadLocal = addLocalVar(g, varSection, varInit, - objType.owner, field.typ, - indirectAccess(castExpr, field, n.info), - useShallowCopy=true) - call.add(threadLocal.newSymNode) - -proc wrapProcForSpawn*(g: ModuleGraph; owner: PSym; spawnExpr: PNode; retType: PType; - barrier, dest: PNode = nil): PNode = - # if 'barrier' != nil, then it is in a 'parallel' section and we - # generate quite different code - let n = spawnExpr[^2] - let spawnKind = spawnResult(retType, barrier!=nil) - case spawnKind - of srVoid: - internalAssert g.config, dest == nil - result = newNodeI(nkStmtList, n.info) - of srFlowVar: - internalAssert g.config, dest == nil - result = newNodeIT(nkStmtListExpr, n.info, retType) - of srByVar: - if dest == nil: localError(g.config, n.info, "'spawn' must not be discarded") - result = newNodeI(nkStmtList, n.info) - - if n.kind notin nkCallKinds: - localError(g.config, n.info, "'spawn' takes a call expression") - return - if optThreadAnalysis in g.config.globalOptions: - if {tfThread, tfNoSideEffect} * n[0].typ.flags == {}: - localError(g.config, n.info, "'spawn' takes a GC safe call expression") - var - threadParam = newSym(skParam, getIdent(g.cache, "thread"), owner, n.info, g.config.options) - argsParam = newSym(skParam, getIdent(g.cache, "args"), owner, n.info, g.config.options) - block: - let ptrType = getSysType(g, n.info, tyPointer) - threadParam.typ = ptrType - argsParam.typ = ptrType - argsParam.position = 1 - - var objType = createObj(g, owner, n.info) - incl(objType.flags, tfFinal) - let castExpr = createCastExpr(argsParam, objType) - - var scratchObj = newSym(skVar, getIdent(g.cache, "scratch"), owner, n.info, g.config.options) - block: - scratchObj.typ = objType - incl(scratchObj.flags, sfFromGeneric) - var varSectionB = newNodeI(nkVarSection, n.info) - varSectionB.addVar(scratchObj.newSymNode) - result.add varSectionB - - var call = newNodeIT(nkCall, n.info, n.typ) - var fn = n.sons[0] - # templates and macros are in fact valid here due to the nature of - # the transformation: - if fn.kind == nkClosure or (fn.typ != nil and fn.typ.callConv == ccClosure): - localError(g.config, n.info, "closure in spawn environment is not allowed") - if not (fn.kind == nkSym and fn.sym.kind in {skProc, skTemplate, skMacro, - skFunc, skMethod, skConverter}): - # for indirect calls we pass the function pointer in the scratchObj - var argType = n[0].typ.skipTypes(abstractInst) - var field = newSym(skField, getIdent(g.cache, "fn"), owner, n.info, g.config.options) - field.typ = argType - objType.addField(field, g.cache) - result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n[0]) - fn = indirectAccess(castExpr, field, n.info) - elif fn.kind == nkSym and fn.sym.kind == skIterator: - localError(g.config, n.info, "iterator in spawn environment is not allowed") - elif fn.typ.callConv == ccClosure: - localError(g.config, n.info, "closure in spawn environment is not allowed") - - call.add(fn) - var varSection = newNodeI(nkVarSection, n.info) - var varInit = newNodeI(nkStmtList, n.info) - if barrier.isNil: - setupArgsForConcurrency(g, n, objType, scratchObj, castExpr, call, - varSection, varInit, result) - else: - setupArgsForParallelism(g, n, objType, scratchObj, castExpr, call, - varSection, varInit, result) - - var barrierAsExpr: PNode = nil - if barrier != nil: - let typ = newType(tyPtr, owner) - typ.rawAddSon(magicsys.getCompilerProc(g, "Barrier").typ) - var field = newSym(skField, getIdent(g.cache, "barrier"), owner, n.info, g.config.options) - field.typ = typ - objType.addField(field, g.cache) - result.add newFastAsgnStmt(newDotExpr(scratchObj, field), barrier) - barrierAsExpr = indirectAccess(castExpr, field, n.info) - - var fvField, fvAsExpr: PNode = nil - if spawnKind == srFlowVar: - var field = newSym(skField, getIdent(g.cache, "fv"), owner, n.info, g.config.options) - field.typ = retType - objType.addField(field, g.cache) - fvField = newDotExpr(scratchObj, field) - fvAsExpr = indirectAccess(castExpr, field, n.info) - # create flowVar: - result.add newFastAsgnStmt(fvField, callProc(spawnExpr[^1])) - if barrier == nil: - result.add callCodegenProc(g, "nimFlowVarCreateSemaphore", fvField.info, - fvField) - - elif spawnKind == srByVar: - var field = newSym(skField, getIdent(g.cache, "fv"), owner, n.info, g.config.options) - field.typ = newType(tyPtr, objType.owner) - field.typ.rawAddSon(retType) - objType.addField(field, g.cache) - fvAsExpr = indirectAccess(castExpr, field, n.info) - result.add newFastAsgnStmt(newDotExpr(scratchObj, field), genAddrOf(dest)) - - let wrapper = createWrapperProc(g, fn, threadParam, argsParam, - varSection, varInit, call, - barrierAsExpr, fvAsExpr, spawnKind) - result.add callCodegenProc(g, "nimSpawn" & $spawnExpr.len, wrapper.info, - wrapper.newSymNode, genAddrOf(scratchObj.newSymNode), nil, spawnExpr) - - if spawnKind == srFlowVar: result.add fvField - +# +# +# The Nim Compiler +# (c) Copyright 2015 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## This module implements threadpool's ``spawn``. + +import ast, types, idents, magicsys, msgs, options, modulegraphs, + lowerings +from trees import getMagic + +proc callProc(a: PNode): PNode = + result = newNodeI(nkCall, a.info) + result.add a + result.typ = a.typ.sons[0] + +# we have 4 cases to consider: +# - a void proc --> nothing to do +# - a proc returning GC'ed memory --> requires a flowVar +# - a proc returning non GC'ed memory --> pass as hidden 'var' parameter +# - not in a parallel environment --> requires a flowVar for memory safety +type + TSpawnResult* = enum + srVoid, srFlowVar, srByVar + TFlowVarKind = enum + fvInvalid # invalid type T for 'FlowVar[T]' + fvGC # FlowVar of a GC'ed type + fvBlob # FlowVar of a blob type + +proc spawnResult*(t: PType; inParallel: bool): TSpawnResult = + if t.isEmptyType: srVoid + elif inParallel and not containsGarbageCollectedRef(t): srByVar + else: srFlowVar + +proc flowVarKind(t: PType): TFlowVarKind = + if t.skipTypes(abstractInst).kind in {tyRef, tyString, tySequence}: fvGC + elif containsGarbageCollectedRef(t): fvInvalid + else: fvBlob + +proc typeNeedsNoDeepCopy(t: PType): bool = + var t = t.skipTypes(abstractInst) + # for the tconvexhull example (and others) we're a bit lax here and pretend + # seqs and strings are *by value* only and 'shallow' doesn't exist! + if t.kind == tyString: return true + # note that seq[T] is fine, but 'var seq[T]' is not, so we need to skip 'var' + # for the stricter check and likewise we can skip 'seq' for a less + # strict check: + if t.kind in {tyVar, tyLent, tySequence}: t = t.lastSon + result = not containsGarbageCollectedRef(t) + +proc addLocalVar(g: ModuleGraph; varSection, varInit: PNode; owner: PSym; typ: PType; + v: PNode; useShallowCopy=false): PSym = + result = newSym(skTemp, getIdent(g.cache, genPrefix), owner, varSection.info, + owner.options) + result.typ = typ + incl(result.flags, sfFromGeneric) + + var vpart = newNodeI(nkIdentDefs, varSection.info, 3) + vpart.sons[0] = newSymNode(result) + vpart.sons[1] = newNodeI(nkEmpty, varSection.info) + vpart.sons[2] = if varInit.isNil: v else: vpart[1] + varSection.add vpart + if varInit != nil: + if useShallowCopy and typeNeedsNoDeepCopy(typ): + varInit.add newFastAsgnStmt(newSymNode(result), v) + else: + let deepCopyCall = newNodeI(nkCall, varInit.info, 3) + deepCopyCall.sons[0] = newSymNode(getSysMagic(g, varSection.info, "deepCopy", mDeepCopy)) + deepCopyCall.sons[1] = newSymNode(result) + deepCopyCall.sons[2] = v + varInit.add deepCopyCall + +discard """ +We generate roughly this: + +proc f_wrapper(thread, args) = + barrierEnter(args.barrier) # for parallel statement + var a = args.a # thread transfer; deepCopy or shallowCopy or no copy + # depending on whether we're in a 'parallel' statement + var b = args.b + var fv = args.fv + + fv.owner = thread # optional + nimArgsPassingDone() # signal parent that the work is done + # + args.fv.blob = f(a, b, ...) + nimFlowVarSignal(args.fv) + + # - or - + f(a, b, ...) + barrierLeave(args.barrier) # for parallel statement + +stmtList: + var scratchObj + scratchObj.a = a + scratchObj.b = b + + nimSpawn(f_wrapper, addr scratchObj) + scratchObj.fv # optional + +""" + +proc createWrapperProc(g: ModuleGraph; f: PNode; threadParam, argsParam: PSym; + varSection, varInit, call, barrier, fv: PNode; + spawnKind: TSpawnResult): PSym = + var body = newNodeI(nkStmtList, f.info) + body.flags.incl nfTransf # do not transform further + + var threadLocalBarrier: PSym + if barrier != nil: + var varSection2 = newNodeI(nkVarSection, barrier.info) + threadLocalBarrier = addLocalVar(g, varSection2, nil, argsParam.owner, + barrier.typ, barrier) + body.add varSection2 + body.add callCodegenProc(g, "barrierEnter", threadLocalBarrier.info, + threadLocalBarrier.newSymNode) + var threadLocalProm: PSym + if spawnKind == srByVar: + threadLocalProm = addLocalVar(g, varSection, nil, argsParam.owner, fv.typ, fv) + elif fv != nil: + internalAssert g.config, fv.typ.kind == tyGenericInst + threadLocalProm = addLocalVar(g, varSection, nil, argsParam.owner, fv.typ, fv) + body.add varSection + body.add varInit + if fv != nil and spawnKind != srByVar: + # generate: + # fv.owner = threadParam + body.add newAsgnStmt(indirectAccess(threadLocalProm.newSymNode, + "owner", fv.info, g.cache), threadParam.newSymNode) + + body.add callCodegenProc(g, "nimArgsPassingDone", threadParam.info, + threadParam.newSymNode) + if spawnKind == srByVar: + body.add newAsgnStmt(genDeref(threadLocalProm.newSymNode), call) + elif fv != nil: + let fk = fv.typ.sons[1].flowVarKind + if fk == fvInvalid: + localError(g.config, f.info, "cannot create a flowVar of type: " & + typeToString(fv.typ.sons[1])) + body.add newAsgnStmt(indirectAccess(threadLocalProm.newSymNode, + if fk == fvGC: "data" else: "blob", fv.info, g.cache), call) + if fk == fvGC: + let incRefCall = newNodeI(nkCall, fv.info, 2) + incRefCall.sons[0] = newSymNode(getSysMagic(g, fv.info, "GCref", mGCref)) + incRefCall.sons[1] = indirectAccess(threadLocalProm.newSymNode, + "data", fv.info, g.cache) + body.add incRefCall + if barrier == nil: + # by now 'fv' is shared and thus might have beeen overwritten! we need + # to use the thread-local view instead: + body.add callCodegenProc(g, "nimFlowVarSignal", threadLocalProm.info, + threadLocalProm.newSymNode) + else: + body.add call + if barrier != nil: + body.add callCodegenProc(g, "barrierLeave", threadLocalBarrier.info, + threadLocalBarrier.newSymNode) + + var params = newNodeI(nkFormalParams, f.info) + params.add newNodeI(nkEmpty, f.info) + params.add threadParam.newSymNode + params.add argsParam.newSymNode + + var t = newType(tyProc, threadParam.owner) + t.rawAddSon nil + t.rawAddSon threadParam.typ + t.rawAddSon argsParam.typ + t.n = newNodeI(nkFormalParams, f.info) + t.n.add newNodeI(nkEffectList, f.info) + t.n.add threadParam.newSymNode + t.n.add argsParam.newSymNode + + let name = (if f.kind == nkSym: f.sym.name.s else: genPrefix) & "Wrapper" + result = newSym(skProc, getIdent(g.cache, name), argsParam.owner, f.info, + argsParam.options) + let emptyNode = newNodeI(nkEmpty, f.info) + result.ast = newProcNode(nkProcDef, f.info, body = body, + params = params, name = newSymNode(result), pattern = emptyNode, + genericParams = emptyNode, pragmas = emptyNode, + exceptions = emptyNode) + result.typ = t + +proc createCastExpr(argsParam: PSym; objType: PType): PNode = + result = newNodeI(nkCast, argsParam.info) + result.add newNodeI(nkEmpty, argsParam.info) + result.add newSymNode(argsParam) + result.typ = newType(tyPtr, objType.owner) + result.typ.rawAddSon(objType) + +proc setupArgsForConcurrency(g: ModuleGraph; n: PNode; objType: PType; scratchObj: PSym, + castExpr, call, + varSection, varInit, result: PNode) = + let formals = n[0].typ.n + let tmpName = getIdent(g.cache, genPrefix) + for i in 1 ..< n.len: + # we pick n's type here, which hopefully is 'tyArray' and not + # 'tyOpenArray': + var argType = n[i].typ.skipTypes(abstractInst) + if i < formals.len and formals[i].typ.kind in {tyVar, tyLent}: + localError(g.config, n[i].info, "'spawn'ed function cannot have a 'var' parameter") + #elif containsTyRef(argType): + # localError(n[i].info, "'spawn'ed function cannot refer to 'ref'/closure") + + let fieldname = if i < formals.len: formals[i].sym.name else: tmpName + var field = newSym(skField, fieldname, objType.owner, n.info, g.config.options) + field.typ = argType + objType.addField(field, g.cache) + result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n[i]) + + let temp = addLocalVar(g, varSection, varInit, objType.owner, argType, + indirectAccess(castExpr, field, n.info)) + call.add(newSymNode(temp)) + +proc getRoot*(n: PNode): PSym = + ## ``getRoot`` takes a *path* ``n``. A path is an lvalue expression + ## like ``obj.x[i].y``. The *root* of a path is the symbol that can be + ## determined as the owner; ``obj`` in the example. + case n.kind + of nkSym: + if n.sym.kind in {skVar, skResult, skTemp, skLet, skForVar}: + result = n.sym + of nkDotExpr, nkBracketExpr, nkHiddenDeref, nkDerefExpr, + nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr: + result = getRoot(n.sons[0]) + of nkHiddenStdConv, nkHiddenSubConv, nkConv: + result = getRoot(n.sons[1]) + of nkCallKinds: + if getMagic(n) == mSlice: result = getRoot(n.sons[1]) + else: discard + +proc setupArgsForParallelism(g: ModuleGraph; n: PNode; objType: PType; scratchObj: PSym; + castExpr, call, + varSection, varInit, result: PNode) = + let formals = n[0].typ.n + let tmpName = getIdent(g.cache, genPrefix) + # we need to copy the foreign scratch object fields into local variables + # for correctness: These are called 'threadLocal' here. + for i in 1 ..< n.len: + let n = n[i] + let argType = skipTypes(if i < formals.len: formals[i].typ else: n.typ, + abstractInst) + #if containsTyRef(argType): + # localError(n.info, "'spawn'ed function cannot refer to 'ref'/closure") + + let fieldname = if i < formals.len: formals[i].sym.name else: tmpName + var field = newSym(skField, fieldname, objType.owner, n.info, g.config.options) + + if argType.kind in {tyVarargs, tyOpenArray}: + # important special case: we always create a zero-copy slice: + let slice = newNodeI(nkCall, n.info, 4) + slice.typ = n.typ + slice.sons[0] = newSymNode(createMagic(g, "slice", mSlice)) + slice.sons[0].typ = getSysType(g, n.info, tyInt) # fake type + var fieldB = newSym(skField, tmpName, objType.owner, n.info, g.config.options) + fieldB.typ = getSysType(g, n.info, tyInt) + objType.addField(fieldB, g.cache) + + if getMagic(n) == mSlice: + let a = genAddrOf(n[1]) + field.typ = a.typ + objType.addField(field, g.cache) + result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a) + + var fieldA = newSym(skField, tmpName, objType.owner, n.info, g.config.options) + fieldA.typ = getSysType(g, n.info, tyInt) + objType.addField(fieldA, g.cache) + result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldA), n[2]) + result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldB), n[3]) + + let threadLocal = addLocalVar(g, varSection,nil, objType.owner, fieldA.typ, + indirectAccess(castExpr, fieldA, n.info), + useShallowCopy=true) + slice.sons[2] = threadLocal.newSymNode + else: + let a = genAddrOf(n) + field.typ = a.typ + objType.addField(field, g.cache) + result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a) + result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldB), genHigh(g, n)) + + slice.sons[2] = newIntLit(g, n.info, 0) + # the array itself does not need to go through a thread local variable: + slice.sons[1] = genDeref(indirectAccess(castExpr, field, n.info)) + + let threadLocal = addLocalVar(g, varSection,nil, objType.owner, fieldB.typ, + indirectAccess(castExpr, fieldB, n.info), + useShallowCopy=true) + slice.sons[3] = threadLocal.newSymNode + call.add slice + elif (let size = computeSize(g.config, argType); size < 0 or size > 16) and + n.getRoot != nil: + # it is more efficient to pass a pointer instead: + let a = genAddrOf(n) + field.typ = a.typ + objType.addField(field, g.cache) + result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a) + let threadLocal = addLocalVar(g, varSection,nil, objType.owner, field.typ, + indirectAccess(castExpr, field, n.info), + useShallowCopy=true) + call.add(genDeref(threadLocal.newSymNode)) + else: + # boring case + field.typ = argType + objType.addField(field, g.cache) + result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n) + let threadLocal = addLocalVar(g, varSection, varInit, + objType.owner, field.typ, + indirectAccess(castExpr, field, n.info), + useShallowCopy=true) + call.add(threadLocal.newSymNode) + +proc wrapProcForSpawn*(g: ModuleGraph; owner: PSym; spawnExpr: PNode; retType: PType; + barrier, dest: PNode = nil): PNode = + # if 'barrier' != nil, then it is in a 'parallel' section and we + # generate quite different code + let n = spawnExpr[^2] + let spawnKind = spawnResult(retType, barrier!=nil) + case spawnKind + of srVoid: + internalAssert g.config, dest == nil + result = newNodeI(nkStmtList, n.info) + of srFlowVar: + internalAssert g.config, dest == nil + result = newNodeIT(nkStmtListExpr, n.info, retType) + of srByVar: + if dest == nil: localError(g.config, n.info, "'spawn' must not be discarded") + result = newNodeI(nkStmtList, n.info) + + if n.kind notin nkCallKinds: + localError(g.config, n.info, "'spawn' takes a call expression") + return + if optThreadAnalysis in g.config.globalOptions: + if {tfThread, tfNoSideEffect} * n[0].typ.flags == {}: + localError(g.config, n.info, "'spawn' takes a GC safe call expression") + var + threadParam = newSym(skParam, getIdent(g.cache, "thread"), owner, n.info, g.config.options) + argsParam = newSym(skParam, getIdent(g.cache, "args"), owner, n.info, g.config.options) + block: + let ptrType = getSysType(g, n.info, tyPointer) + threadParam.typ = ptrType + argsParam.typ = ptrType + argsParam.position = 1 + + var objType = createObj(g, owner, n.info) + incl(objType.flags, tfFinal) + let castExpr = createCastExpr(argsParam, objType) + + var scratchObj = newSym(skVar, getIdent(g.cache, "scratch"), owner, n.info, g.config.options) + block: + scratchObj.typ = objType + incl(scratchObj.flags, sfFromGeneric) + var varSectionB = newNodeI(nkVarSection, n.info) + varSectionB.addVar(scratchObj.newSymNode) + result.add varSectionB + + var call = newNodeIT(nkCall, n.info, n.typ) + var fn = n.sons[0] + # templates and macros are in fact valid here due to the nature of + # the transformation: + if fn.kind == nkClosure or (fn.typ != nil and fn.typ.callConv == ccClosure): + localError(g.config, n.info, "closure in spawn environment is not allowed") + if not (fn.kind == nkSym and fn.sym.kind in {skProc, skTemplate, skMacro, + skFunc, skMethod, skConverter}): + # for indirect calls we pass the function pointer in the scratchObj + var argType = n[0].typ.skipTypes(abstractInst) + var field = newSym(skField, getIdent(g.cache, "fn"), owner, n.info, g.config.options) + field.typ = argType + objType.addField(field, g.cache) + result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n[0]) + fn = indirectAccess(castExpr, field, n.info) + elif fn.kind == nkSym and fn.sym.kind == skIterator: + localError(g.config, n.info, "iterator in spawn environment is not allowed") + elif fn.typ.callConv == ccClosure: + localError(g.config, n.info, "closure in spawn environment is not allowed") + + call.add(fn) + var varSection = newNodeI(nkVarSection, n.info) + var varInit = newNodeI(nkStmtList, n.info) + if barrier.isNil: + setupArgsForConcurrency(g, n, objType, scratchObj, castExpr, call, + varSection, varInit, result) + else: + setupArgsForParallelism(g, n, objType, scratchObj, castExpr, call, + varSection, varInit, result) + + var barrierAsExpr: PNode = nil + if barrier != nil: + let typ = newType(tyPtr, owner) + typ.rawAddSon(magicsys.getCompilerProc(g, "Barrier").typ) + var field = newSym(skField, getIdent(g.cache, "barrier"), owner, n.info, g.config.options) + field.typ = typ + objType.addField(field, g.cache) + result.add newFastAsgnStmt(newDotExpr(scratchObj, field), barrier) + barrierAsExpr = indirectAccess(castExpr, field, n.info) + + var fvField, fvAsExpr: PNode = nil + if spawnKind == srFlowVar: + var field = newSym(skField, getIdent(g.cache, "fv"), owner, n.info, g.config.options) + field.typ = retType + objType.addField(field, g.cache) + fvField = newDotExpr(scratchObj, field) + fvAsExpr = indirectAccess(castExpr, field, n.info) + # create flowVar: + result.add newFastAsgnStmt(fvField, callProc(spawnExpr[^1])) + if barrier == nil: + result.add callCodegenProc(g, "nimFlowVarCreateSemaphore", fvField.info, + fvField) + + elif spawnKind == srByVar: + var field = newSym(skField, getIdent(g.cache, "fv"), owner, n.info, g.config.options) + field.typ = newType(tyPtr, objType.owner) + field.typ.rawAddSon(retType) + objType.addField(field, g.cache) + fvAsExpr = indirectAccess(castExpr, field, n.info) + result.add newFastAsgnStmt(newDotExpr(scratchObj, field), genAddrOf(dest)) + + let wrapper = createWrapperProc(g, fn, threadParam, argsParam, + varSection, varInit, call, + barrierAsExpr, fvAsExpr, spawnKind) + result.add callCodegenProc(g, "nimSpawn" & $spawnExpr.len, wrapper.info, + wrapper.newSymNode, genAddrOf(scratchObj.newSymNode), nil, spawnExpr) + + if spawnKind == srFlowVar: result.add fvField + diff --git a/compiler/suggest.nim b/compiler/suggest.nim index 9e738e8a6..2f92825c0 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -32,11 +32,11 @@ # included from sigmatch.nim -import algorithm, prefixmatches, lineinfos, pathutils, parseutils, linter +import algorithm, prefixmatches, lineinfos, parseutils, linter from wordrecg import wDeprecated, wError, wAddr, wYield, specialWords when defined(nimsuggest): - import passes, tables # importer + import passes, tables, pathutils # importer const sep = '\t' diff --git a/compiler/syntaxes.nim b/compiler/syntaxes.nim index 3e4f65c0b..3b67b3263 100644 --- a/compiler/syntaxes.nim +++ b/compiler/syntaxes.nim @@ -10,7 +10,7 @@ ## Implements the dispatcher for the different parsers. import - strutils, llstream, ast, astalgo, idents, lexer, options, msgs, parser, + strutils, llstream, ast, idents, lexer, options, msgs, parser, filters, filter_tmpl, renderer, lineinfos, pathutils type diff --git a/compiler/transf.nim b/compiler/transf.nim index 4dd348742..60a7ce224 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -19,9 +19,9 @@ # * transforms 'defer' into a 'try finally' statement import - intsets, strutils, options, ast, astalgo, trees, treetab, msgs, lookups, + options, ast, astalgo, trees, msgs, idents, renderer, types, passes, semfold, magicsys, cgmeth, - sempass2, lowerings, injectdestructors, liftlocals, + lowerings, injectdestructors, liftlocals, modulegraphs, lineinfos proc transformBody*(g: ModuleGraph, prc: PSym, cache = true; diff --git a/compiler/trees.nim b/compiler/trees.nim index c878eb1bf..87ab7c00e 100644 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -10,7 +10,7 @@ # tree helper routines import - ast, astalgo, lexer, msgs, strutils, wordrecg, idents + ast, wordrecg, idents proc cyclicTreeAux(n: PNode, visited: var seq[PNode]): bool = if n == nil: return diff --git a/compiler/typesrenderer.nim b/compiler/typesrenderer.nim index 0c4fe01e1..7084349e5 100644 --- a/compiler/typesrenderer.nim +++ b/compiler/typesrenderer.nim @@ -7,7 +7,7 @@ # distribution, for details about the copyright. # -import renderer, strutils, ast, msgs, types, astalgo +import renderer, strutils, ast, types const defaultParamSeparator* = "," diff --git a/compiler/vm.nim b/compiler/vm.nim index bb8c6bbf2..34caec83f 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -13,7 +13,7 @@ import ast except getstr import - strutils, astalgo, msgs, vmdef, vmgen, nimsets, types, passes, + strutils, msgs, vmdef, vmgen, nimsets, types, passes, parser, vmdeps, idents, trees, renderer, options, transf, parseutils, vmmarshal, gorgeimpl, lineinfos, tables, btrees, macrocacheimpl, modulegraphs, sighashes diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim index 723863ca7..425f728e7 100644 --- a/compiler/vmdef.nim +++ b/compiler/vmdef.nim @@ -10,8 +10,7 @@ ## This module contains the type definitions for the new evaluation engine. ## An instruction is 1-3 int32s in memory, it is a register based VM. -import ast, passes, msgs, idents, intsets, options, modulegraphs, lineinfos, - tables, btrees +import ast, passes, idents, intsets, options, modulegraphs, lineinfos const byteExcess* = 128 # we use excess-K for immediates diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index 5130f30c9..1b2538c79 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -7,7 +7,7 @@ # distribution, for details about the copyright. # -import ast, types, msgs, os, streams, options, idents, lineinfos +import ast, types, msgs, os, options, idents, lineinfos proc opSlurp*(file: string, info: TLineInfo, module: PSym; conf: ConfigRef): string = try: diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 37706f1ea..a27cd62c6 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -28,10 +28,8 @@ # this copy depends on the involved types. import - strutils, ast, astalgo, types, msgs, renderer, vmdef, - trees, intsets, magicsys, options, lowerings, lineinfos, transf -import platform -from os import splitFile + strutils, ast, types, msgs, renderer, vmdef, + intsets, magicsys, options, lowerings, lineinfos, transf const debugEchoCode* = defined(nimVMDebug) diff --git a/compiler/writetracking.nim b/compiler/writetracking.nim index 04d3b7a16..b310701ca 100644 --- a/compiler/writetracking.nim +++ b/compiler/writetracking.nim @@ -15,8 +15,7 @@ ## * Computing an aliasing relation based on the assignments. This relation ## is then used to compute the 'writes' and 'escapes' effects. -import intsets, idents, ast, astalgo, trees, renderer, msgs, types, options, - lineinfos +import intsets, idents, ast, trees, msgs, types, options, lineinfos const debug = false |