summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2020-03-04 13:46:42 +0100
committerGitHub <noreply@github.com>2020-03-04 13:46:42 +0100
commit614fb7567c80c3b071394714c3809c005aaad397 (patch)
tree4548c2b1f9d46120e4b0bb6e83a127060e9954ba
parent0809098971080674f723cb219722487e42011fd1 (diff)
downloadNim-614fb7567c80c3b071394714c3809c005aaad397.tar.gz
std/compilesettings implementation (#13584)
* Implement compileSetting() and compileSettingSeq()
* Change from magic to vmop
* better design for querySetting

Co-authored-by: genotrance <dev@genotrance.com>
-rw-r--r--changelog.md12
-rw-r--r--compiler/vmops.nim33
-rw-r--r--lib/std/compilesettings.nim54
-rw-r--r--tests/vm/tcompilesetting.nim19
4 files changed, 118 insertions, 0 deletions
diff --git a/changelog.md b/changelog.md
index 87bf8bd08..ccc969ca6 100644
--- a/changelog.md
+++ b/changelog.md
@@ -78,10 +78,22 @@
 
 ```nim
 
+type
+  Foo = object
+    col, pos: string
 
+proc setColor(f: var Foo; r, g, b: int) = f.col = $(r, g, b)
+proc setPosition(f: var Foo; x, y: float) = f.pos = $(x, y)
+
+var f: Foo
+with(f, setColor(2, 3, 4), setPosition(0.0, 1.0))
+echo f
 
 ```
+
 - Added `times.isLeapDay`
+- Added a new module, `std / compilesettings` for querying the compiler about
+  diverse configuration settings.
 
 
 ## Library changes
diff --git a/compiler/vmops.nim b/compiler/vmops.nim
index 1e3a258f3..8cb2a0552 100644
--- a/compiler/vmops.nim
+++ b/compiler/vmops.nim
@@ -102,6 +102,35 @@ proc staticWalkDirImpl(path: string, relative: bool): PNode =
     result.add newTree(nkTupleConstr, newIntNode(nkIntLit, k.ord),
                               newStrNode(nkStrLit, f))
 
+from std / compilesettings import SingleValueSetting, MultipleValueSetting
+
+proc querySettingImpl(a: VmArgs, conf: ConfigRef, switch: BiggestInt): string =
+  case SingleValueSetting(switch)
+  of arguments: result = conf.arguments
+  of outFile: result = conf.outFile.string
+  of outDir: result = conf.outDir.string
+  of nimcacheDir: result = conf.nimcacheDir.string
+  of projectName: result = conf.projectName
+  of projectPath: result = conf.projectPath.string
+  of projectFull: result = conf.projectFull.string
+  of command: result = conf.command
+  of commandLine: result = conf.commandLine
+  of linkOptions: result = conf.linkOptions
+  of compileOptions: result = conf.compileOptions
+  of ccompilerPath: result = conf.cCompilerPath
+
+proc querySettingSeqImpl(a: VmArgs, conf: ConfigRef, switch: BiggestInt): seq[string] =
+  template copySeq(field: untyped): untyped =
+    for i in field: result.add i.string
+
+  case MultipleValueSetting(switch)
+  of nimblePaths: copySeq(conf.nimblePaths)
+  of searchPaths: copySeq(conf.searchPaths)
+  of lazyPaths: copySeq(conf.lazyPaths)
+  of commandArgs: result = conf.commandArgs
+  of cincludes: copySeq(conf.cIncludes)
+  of clibs: copySeq(conf.cLibs)
+
 proc registerAdditionalOps*(c: PCtx) =
   proc gorgeExWrapper(a: VmArgs) =
     let (s, e) = opGorge(getString(a, 0), getString(a, 1), getString(a, 2),
@@ -152,6 +181,10 @@ proc registerAdditionalOps*(c: PCtx) =
     systemop getCurrentException
     registerCallback c, "stdlib.*.staticWalkDir", proc (a: VmArgs) {.nimcall.} =
       setResult(a, staticWalkDirImpl(getString(a, 0), getBool(a, 1)))
+    registerCallback c, "stdlib.compilesettings.querySetting", proc (a: VmArgs) {.nimcall.} =
+      setResult(a, querySettingImpl(a, c.config, getInt(a, 0)))
+    registerCallback c, "stdlib.compilesettings.querySettingSeq", proc (a: VmArgs) {.nimcall.} =
+      setResult(a, querySettingSeqImpl(a, c.config, getInt(a, 0)))
 
     if defined(nimsuggest) or c.config.cmd == cmdCheck:
       discard "don't run staticExec for 'nim suggest'"
diff --git a/lib/std/compilesettings.nim b/lib/std/compilesettings.nim
new file mode 100644
index 000000000..12204658d
--- /dev/null
+++ b/lib/std/compilesettings.nim
@@ -0,0 +1,54 @@
+#
+#
+#           The Nim Compiler
+#        (c) Copyright 2020 Nim Contributors
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## This module allows querying the compiler about
+## diverse configuration settings.
+
+# Note: Only add new enum values at the end to ensure binary compatibility with
+# other Nim compiler versions!
+
+type
+  SingleValueSetting* {.pure.} = enum ## \
+                      ## settings resulting in a single string value
+    arguments,        ## experimental: the arguments passed after '-r'
+    outFile,          ## experimental: the output file
+    outDir,           ## the output directory
+    nimcacheDir,      ## the location of the 'nimcache' directory
+    projectName,      ## the project's name that is being compiled
+    projectPath,      ## experimental: some path to the project that is being compiled
+    projectFull,      ## the full path to the project that is being compiled
+    command,          ## experimental: the command (e.g. 'c', 'cpp', 'doc') passed to
+                      ## the Nim compiler
+    commandLine,      ## experimental: the command line passed to Nim
+    linkOptions,      ## additional options passed to the linker
+    compileOptions,   ## additional options passed to the C/C++ compiler
+    ccompilerPath     ## the path to the C/C++ compiler
+
+  MultipleValueSetting* {.pure.} = enum ## \
+                      ## settings resulting in a seq of string values
+    nimblePaths,      ## the nimble path(s)
+    searchPaths,      ## the search path for modules
+    lazyPaths,        ## experimental: even more paths
+    commandArgs,      ## the arguments passed to the Nim compiler
+    cincludes,        ## the #include paths passed to the C/C++ compiler
+    clibs             ## libraries passed to the C/C++ compiler
+
+proc querySetting*(setting: SingleValueSetting): string {.
+  compileTime, noSideEffect.} = discard
+  ## Can be used to get a string compile-time option. Example:
+  ##
+  ## .. code-block:: Nim
+  ##   const nimcache = querySetting(SingleValueSetting.nimcacheDir)
+
+proc querySettingSeq*(setting: MultipleValueSetting): seq[string] {.
+  compileTime, noSideEffect.} = discard
+  ## Can be used to get a multi-string compile-time option. Example:
+  ##
+  ## .. code-block:: Nim
+  ##   const nimblePaths = compileSettingSeq(MultipleValueSetting.nimblePaths)
diff --git a/tests/vm/tcompilesetting.nim b/tests/vm/tcompilesetting.nim
new file mode 100644
index 000000000..0e936d377
--- /dev/null
+++ b/tests/vm/tcompilesetting.nim
@@ -0,0 +1,19 @@
+discard """
+cmd: "nim c --nimcache:myNimCache --nimblePath:myNimblePath $file"
+joinable: false
+"""
+
+import strutils
+
+import std / compilesettings
+
+const
+  nc = querySetting(nimcacheDir)
+  np = querySettingSeq(nimblePaths)
+
+static:
+  echo nc
+  echo np
+
+doAssert "myNimCache" in nc
+doAssert "myNimblePath" in np[0]