summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorTimothee Cour <timothee.cour2@gmail.com>2018-12-18 00:07:12 -0800
committerAndreas Rumpf <rumpf_a@web.de>2018-12-18 09:07:12 +0100
commitc4e3c4ca2d0a1f44ed1e3dd9db564b66031f0843 (patch)
tree9aac56357dfbad2ac7bad74ef31670e4d6d99b16
parentbb1160b73cc3410ce7a0949f67d2fa7f5b425ab4 (diff)
downloadNim-c4e3c4ca2d0a1f44ed1e3dd9db564b66031f0843.tar.gz
add `getCurrentCompilerExe` to vmops (eg allows to get nim compiler at CT); add tests for vmops (#9925)
-rw-r--r--changelog.md3
-rw-r--r--compiler/vmops.nim5
-rw-r--r--lib/pure/os.nim9
-rw-r--r--lib/system/nimscript.nim1
-rw-r--r--tests/vm/tgorge.nim2
-rw-r--r--tests/vm/tvmops.nim47
6 files changed, 65 insertions, 2 deletions
diff --git a/changelog.md b/changelog.md
index 353d07205..ecdd26086 100644
--- a/changelog.md
+++ b/changelog.md
@@ -95,6 +95,9 @@ proc enumToString*(enums: openArray[enum]): string =
 
 - Added `os.relativePath`.
 - Added `parseopt.remainingArgs`.
+- Added `os.getCurrentCompilerExe` (implmented as `getAppFilename` at CT),
+  can be used to retrive the currently executing compiler.
+
 
 ### Library changes
 
diff --git a/compiler/vmops.nim b/compiler/vmops.nim
index 75873bfe8..56c97dec6 100644
--- a/compiler/vmops.nim
+++ b/compiler/vmops.nim
@@ -13,7 +13,7 @@ from math import sqrt, ln, log10, log2, exp, round, arccos, arcsin,
   arctan, arctan2, cos, cosh, hypot, sinh, sin, tan, tanh, pow, trunc,
   floor, ceil, `mod`
 
-from os import getEnv, existsEnv, dirExists, fileExists, putEnv, walkDir
+from os import getEnv, existsEnv, dirExists, fileExists, putEnv, walkDir, getAppFilename
 
 template mathop(op) {.dirty.} =
   registerCallback(c, "stdlib.math." & astToStr(op), `op Wrapper`)
@@ -120,3 +120,6 @@ proc registerAdditionalOps*(c: PCtx) =
       setResult(a, staticWalkDirImpl(getString(a, 0), getBool(a, 1)))
     systemop gorgeEx
   macrosop getProjectPath
+
+  registerCallback c, "stdlib.os.getCurrentCompilerExe", proc (a: VmArgs) {.nimcall.} =
+    setResult(a, getAppFilename())
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index 1ad276b0a..68c1e28a2 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -1419,6 +1419,12 @@ type
     pcDir,                ## path refers to a directory
     pcLinkToDir           ## path refers to a symbolic link to a directory
 
+proc getCurrentCompilerExe*(): string {.compileTime.} = discard
+  ## `getAppFilename` at CT; can be used to retrive the currently executing
+  ## Nim compiler from a Nim or nimscript program, or the nimble binary
+  ## inside a nimble program (likewise with other binaries built from
+  ## compiler API).
+
 when defined(posix) and not defined(nimscript):
   proc getSymlinkFileKind(path: string): PathComponent =
     # Helper function.
@@ -2118,7 +2124,8 @@ when defined(haiku):
       result = ""
 
 proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect], noNimScript.} =
-  ## Returns the filename of the application's executable.
+  ## Returns the filename of the application's executable. See also
+  ## `getCurrentCompilerExe`.
   ##
   ## This procedure will resolve symlinks.
 
diff --git a/lib/system/nimscript.nim b/lib/system/nimscript.nim
index fc4b574e4..34daf30a9 100644
--- a/lib/system/nimscript.nim
+++ b/lib/system/nimscript.nim
@@ -143,6 +143,7 @@ proc existsDir*(dir: string): bool =
 
 proc selfExe*(): string =
   ## Returns the currently running nim or nimble executable.
+  # TODO: consider making this as deprecated alias of `getCurrentCompilerExe`
   builtin
 
 proc toExe*(filename: string): string =
diff --git a/tests/vm/tgorge.nim b/tests/vm/tgorge.nim
index 11c49a4cc..1f77d2c95 100644
--- a/tests/vm/tgorge.nim
+++ b/tests/vm/tgorge.nim
@@ -10,6 +10,8 @@ import os
 template getScriptDir(): string =
   parentDir(instantiationInfo(-1, true).filename)
 
+# See also simpler test in Nim/tests/vm/tvmops.nim for a simpler
+# cross platform way.
 block gorge:
   const
     execName = when defined(windows): "tgorge.bat" else: "./tgorge.sh"
diff --git a/tests/vm/tvmops.nim b/tests/vm/tvmops.nim
new file mode 100644
index 000000000..c9caaf32b
--- /dev/null
+++ b/tests/vm/tvmops.nim
@@ -0,0 +1,47 @@
+#[
+test for vmops.nim
+]#
+import os
+import math
+import strutils
+
+template forceConst(a: untyped): untyped =
+  ## Force evaluation at CT, useful for example here:
+  ## `callFoo(forceConst(getBar1()), getBar2())`
+  ## instead of:
+  ##  block:
+  ##    const a = getBar1()
+  ##    `callFoo(a, getBar2())`
+  const ret = a
+  ret
+
+static:
+  # TODO: add more tests
+  block: #getAppFilename, gorgeEx, gorge
+    const nim = getCurrentCompilerExe()
+    let ret = gorgeEx(nim & " --version")
+    doAssert ret.exitCode == 0
+    doAssert ret.output.contains "Nim Compiler"
+    let ret2 = gorgeEx(nim & " --unexistant")
+    doAssert ret2.exitCode != 0
+    let output3 = gorge(nim & " --version")
+    doAssert output3.contains "Nim Compiler"
+
+  block:
+    const key = "D20181210T175037"
+    const val = "foo"
+    putEnv(key, val)
+    doAssert existsEnv(key)
+    doAssert getEnv(key) == val
+
+  block:
+    # sanity check (we probably don't need to test for all ops)
+    const a1 = arcsin 0.3
+    let a2 = arcsin 0.3
+    doAssert a1 == a2
+
+block:
+  # Check against bugs like #9176
+  doAssert getCurrentCompilerExe() == forceConst(getCurrentCompilerExe())
+  if false: #pending #9176
+    doAssert gorgeEx("unexistant") == forceConst(gorgeEx("unexistant"))