summary refs log tree commit diff stats
path: root/compiler/ic/replayer.nim
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2021-01-12 09:36:51 +0100
committerGitHub <noreply@github.com>2021-01-12 09:36:51 +0100
commitcf6dd57efeb3f4dba21102b75fd91c5a84224eaf (patch)
tree7fd9c574d0d620c7f9465e74e505aa10a7a989c7 /compiler/ic/replayer.nim
parentbf184bcdd9d2d25ea1da1c6c9b9abd7dfd2bd83b (diff)
downloadNim-cf6dd57efeb3f4dba21102b75fd91c5a84224eaf.tar.gz
IC: next steps (#16632)
* removed dead code
* beginnings of a rodfile reader
* IC: record global VM state changes and pragma state changes
* IC: replay pragmas and VM state changes
* implemented rod load file simuation for easier, extensive testing
* critical bugfix
* IC: stress test logic; should also help with recursive module dependencies; WIP
* IC: loading from .rod files begins to work reliably
* removed ugly hacks
* yet another silly mistake
Diffstat (limited to 'compiler/ic/replayer.nim')
-rw-r--r--compiler/ic/replayer.nim89
1 files changed, 89 insertions, 0 deletions
diff --git a/compiler/ic/replayer.nim b/compiler/ic/replayer.nim
new file mode 100644
index 000000000..b4dd05965
--- /dev/null
+++ b/compiler/ic/replayer.nim
@@ -0,0 +1,89 @@
+#
+#
+#           The Nim Compiler
+#        (c) Copyright 2020 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## Module that contains code to replay global VM state changes and pragma
+## state like ``{.compile: "foo.c".}``. For IC (= Incremental compilation)
+## support.
+
+import ".." / [ast, modulegraphs, trees, extccomp, btrees,
+  msgs, lineinfos, pathutils, options]
+
+import tables
+
+proc replayStateChanges*(module: PSym; g: ModuleGraph) =
+  let list = module.ast
+  assert list != nil
+  assert list.kind == nkStmtList
+  for n in list:
+    assert n.kind == nkReplayAction
+    # Fortunately only a tiny subset of the available pragmas need to
+    # be replayed here. This is always a subset of ``pragmas.stmtPragmas``.
+    if n.len >= 2:
+      internalAssert g.config, n[0].kind == nkStrLit and n[1].kind == nkStrLit
+      case n[0].strVal
+      of "hint": message(g.config, n.info, hintUser, n[1].strVal)
+      of "warning": message(g.config, n.info, warnUser, n[1].strVal)
+      of "error": localError(g.config, n.info, errUser, n[1].strVal)
+      of "compile":
+        internalAssert g.config, n.len == 4 and n[2].kind == nkStrLit
+        let cname = AbsoluteFile n[1].strVal
+        var cf = Cfile(nimname: splitFile(cname).name, cname: cname,
+                       obj: AbsoluteFile n[2].strVal,
+                       flags: {CfileFlag.External},
+                       customArgs: n[3].strVal)
+        extccomp.addExternalFileToCompile(g.config, cf)
+      of "link":
+        extccomp.addExternalFileToLink(g.config, AbsoluteFile n[1].strVal)
+      of "passl":
+        extccomp.addLinkOption(g.config, n[1].strVal)
+      of "passc":
+        extccomp.addCompileOption(g.config, n[1].strVal)
+      of "localpassc":
+        extccomp.addLocalCompileOption(g.config, n[1].strVal, toFullPathConsiderDirty(g.config, module.info.fileIndex))
+      of "cppdefine":
+        options.cppDefine(g.config, n[1].strVal)
+      of "inc":
+        let destKey = n[1].strVal
+        let by = n[2].intVal
+        let v = getOrDefault(g.cacheCounters, destKey)
+        g.cacheCounters[destKey] = v+by
+      of "put":
+        let destKey = n[1].strVal
+        let key = n[2].strVal
+        let val = n[3]
+        if not contains(g.cacheTables, destKey):
+          g.cacheTables[destKey] = initBTree[string, PNode]()
+        if not contains(g.cacheTables[destKey], key):
+          g.cacheTables[destKey].add(key, val)
+        else:
+          internalError(g.config, n.info, "key already exists: " & key)
+      of "incl":
+        let destKey = n[1].strVal
+        let val = n[2]
+        if not contains(g.cacheSeqs, destKey):
+          g.cacheSeqs[destKey] = newTree(nkStmtList, val)
+        else:
+          block search:
+            for existing in g.cacheSeqs[destKey]:
+              if exprStructuralEquivalent(existing, val, strictSymEquality=true):
+                break search
+            g.cacheSeqs[destKey].add val
+      of "add":
+        let destKey = n[1].strVal
+        let val = n[2]
+        if not contains(g.cacheSeqs, destKey):
+          g.cacheSeqs[destKey] = newTree(nkStmtList, val)
+        else:
+          g.cacheSeqs[destKey].add val
+      else:
+        internalAssert g.config, false
+
+#  of nkMethodDef:
+#    methodDef(g, n[namePos].sym, fromCache=true)
+