summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorgenotrance <dev@genotrance.com>2018-04-12 06:59:14 -0500
committerAndreas Rumpf <rumpf_a@web.de>2018-04-12 13:59:14 +0200
commitc3cc52087fb46e7898e9099945667204e40befbc (patch)
treef655aaebac559f680d8d02431ae996e55ab23c17
parent84982e5e1787d0b3c36ae185c5c75f7764543054 (diff)
downloadNim-c3cc52087fb46e7898e9099945667204e40befbc.tar.gz
Added a few useful os calls to VM (#7440)
-rw-r--r--changelog.md1
-rw-r--r--compiler/vmops.nim48
-rw-r--r--lib/core/macros.nim4
-rw-r--r--tests/vm/tvmmisc.nim24
4 files changed, 55 insertions, 22 deletions
diff --git a/changelog.md b/changelog.md
index d3ac27d6d..689c6d253 100644
--- a/changelog.md
+++ b/changelog.md
@@ -54,3 +54,4 @@
 
 - The VM's instruction count limit was raised to 1 billion instructions in order
   to support more complex computations at compile-time.
+- Added ``macros.getProjectPath`` and ``ospaths.putEnv`` procs to VM.
diff --git a/compiler/vmops.nim b/compiler/vmops.nim
index 2a00f207a..f7debe2df 100644
--- a/compiler/vmops.nim
+++ b/compiler/vmops.nim
@@ -13,7 +13,9 @@ from math import sqrt, ln, log10, log2, exp, round, arccos, arcsin,
   arctan, arctan2, cos, cosh, hypot, sinh, sin, tan, tanh, pow, trunc,
   floor, ceil, fmod
 
-from os import getEnv, existsEnv, dirExists, fileExists, walkDir
+from os import getEnv, existsEnv, dirExists, fileExists, putEnv, walkDir
+
+from options import gProjectPath
 
 template mathop(op) {.dirty.} =
   registerCallback(c, "stdlib.math." & astToStr(op), `op Wrapper`)
@@ -27,6 +29,9 @@ template ospathsop(op) {.dirty.} =
 template systemop(op) {.dirty.} =
   registerCallback(c, "stdlib.system." & astToStr(op), `op Wrapper`)
 
+template macrosop(op) {.dirty.} =
+  registerCallback(c, "stdlib.macros." & astToStr(op), `op Wrapper`)
+
 template wrap1f_math(op) {.dirty.} =
   proc `op Wrapper`(a: VmArgs) {.nimcall.} =
     setResult(a, op(getFloat(a, 0)))
@@ -37,30 +42,30 @@ template wrap2f_math(op) {.dirty.} =
     setResult(a, op(getFloat(a, 0), getFloat(a, 1)))
   mathop op
 
-template wrap1s_os(op) {.dirty.} =
+template wrap0(op, modop) {.dirty.} =
   proc `op Wrapper`(a: VmArgs) {.nimcall.} =
-    setResult(a, op(getString(a, 0)))
-  osop op
+    setResult(a, op())
+  modop op
 
-template wrap1s_ospaths(op) {.dirty.} =
+template wrap1s(op, modop) {.dirty.} =
   proc `op Wrapper`(a: VmArgs) {.nimcall.} =
     setResult(a, op(getString(a, 0)))
-  ospathsop op
+  modop op
 
-template wrap2s_ospaths(op) {.dirty.} =
+template wrap2s(op, modop) {.dirty.} =
   proc `op Wrapper`(a: VmArgs) {.nimcall.} =
     setResult(a, op(getString(a, 0), getString(a, 1)))
-  ospathsop op
+  modop op
 
-template wrap1s_system(op) {.dirty.} =
+template wrap1svoid(op, modop) {.dirty.} =
   proc `op Wrapper`(a: VmArgs) {.nimcall.} =
-    setResult(a, op(getString(a, 0)))
-  systemop op
+    op(getString(a, 0))
+  modop op
 
-template wrap2svoid_system(op) {.dirty.} =
+template wrap2svoid(op, modop) {.dirty.} =
   proc `op Wrapper`(a: VmArgs) {.nimcall.} =
     op(getString(a, 0), getString(a, 1))
-  systemop op
+  modop op
 
 proc getCurrentExceptionMsgWrapper(a: VmArgs) {.nimcall.} =
   setResult(a, if a.currentException.isNil: ""
@@ -77,6 +82,9 @@ proc gorgeExWrapper(a: VmArgs) {.nimcall.} =
                        a.currentLineInfo)
   setResult a, newTree(nkPar, newStrNode(nkStrLit, s), newIntNode(nkIntLit, e))
 
+proc getProjectPathWrapper(a: VmArgs) {.nimcall.} =
+  setResult a, gProjectPath
+
 proc registerAdditionalOps*(c: PCtx) =
   wrap1f_math(sqrt)
   wrap1f_math(ln)
@@ -101,13 +109,15 @@ proc registerAdditionalOps*(c: PCtx) =
   wrap1f_math(ceil)
   wrap2f_math(fmod)
 
-  wrap2s_ospaths(getEnv)
-  wrap1s_ospaths(existsEnv)
-  wrap1s_os(dirExists)
-  wrap1s_os(fileExists)
-  wrap2svoid_system(writeFile)
-  wrap1s_system(readFile)
+  wrap2s(getEnv, ospathsop)
+  wrap1s(existsEnv, ospathsop)
+  wrap2svoid(putEnv, ospathsop)
+  wrap1s(dirExists, osop)
+  wrap1s(fileExists, osop)
+  wrap2svoid(writeFile, systemop)
+  wrap1s(readFile, systemop)
   systemop getCurrentExceptionMsg
   registerCallback c, "stdlib.*.staticWalkDir", proc (a: VmArgs) {.nimcall.} =
     setResult(a, staticWalkDirImpl(getString(a, 0), getBool(a, 1)))
   systemop gorgeEx
+  macrosop getProjectPath
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index 9edaab237..3614cf71a 100644
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -1293,3 +1293,7 @@ macro unpackVarargs*(callee: untyped; args: varargs[untyped]): untyped =
   result = newCall(callee)
   for i in 0 ..< args.len:
     result.add args[i]
+
+proc getProjectPath*(): string = discard
+  ## Returns the path to the currently compiling project
+
diff --git a/tests/vm/tvmmisc.nim b/tests/vm/tvmmisc.nim
index 42a58fa8f..472660bc2 100644
--- a/tests/vm/tvmmisc.nim
+++ b/tests/vm/tvmmisc.nim
@@ -1,5 +1,8 @@
 # bug #4462
 import macros
+import os
+import ospaths
+import strutils
 
 block:
   proc foo(t: typedesc) {.compileTime.} =
@@ -18,7 +21,7 @@ block:
 # #6379
 static:
   import algorithm
-  
+
   var numArray = [1, 2, 3, 4, -1]
   numArray.sort(cmp)
   assert numArray == [-1, 1, 2, 3, 4]
@@ -57,10 +60,25 @@ block:
     result = @[0]
     result.setLen(2)
     var tmp: int
-      
-    for i in 0 .. <2:
+
+    for i in 0 ..< 2:
       inc tmp
       result[i] = tmp
 
   const fact1000 = abc()
   assert fact1000 == @[1, 2]
+
+# Tests for VM ops
+block:
+  static:
+    assert "vm" in getProjectPath()
+
+    let b = getEnv("UNSETENVVAR")
+    assert b == ""
+    assert existsEnv("UNSERENVVAR") == false
+    putEnv("UNSETENVVAR", "VALUE")
+    assert getEnv("UNSETENVVAR") == "VALUE"
+    assert existsEnv("UNSETENVVAR") == true
+
+    assert fileExists("MISSINGFILE") == false
+    assert dirExists("MISSINGDIR") == false